This had me for a moment. A quick gotcha, for me, because it was causing some problems in a script of mine.
If you explode an empty string, you'll get an array with one element - an empty string, and not an empty array or string as you may think.
For example:
<?php
$string = "";
$numbers = explode(",", $string); // Array with one element, "".
$string = "1,2,3";
$numbers = explode(",", $string); // Array with three elements
?>
explode
(PHP 4, PHP 5)
explode — 文字列を文字列により分割する
説明
array explode ( string $delimiter, string $string [, int $limit] )文字列の配列を返します。この配列の各要素は、 string を文字列 delimiter で区切った部分文字列となります。 limit が指定された場合、返される配列には 最大 limit の要素が含まれ、その最後の要素には string の残りの部分が全て含まれます。
空の文字列 ("") が delimiter として使用された場合、 explode() は FALSE を返します。delimiter に引数 string に含まれていない値が含まれている場合、 explode() は、引数 string を返します。
もし limit パラメータが負の場合、 最後の -limit 個の要素を除く全ての構成要素が返されます。 この特徴は PHP 5.1.0 で追加されました。
歴史的理由により、implode() はいずれのパラメータ順も受け入れることができますが、 explode() はそうできません。 string 引数の前に必ず delimiter 引数がくるように確認する必要があります。
注意: パラメータ limit は、PHP 4.0.1 で追加されました。
例 2354. explode() の例
<?php
// 例 1
$pizza = "piece1 piece2 piece3 piece4 piece5 piece6";
$pieces = explode(" ", $pizza);
echo $pieces[0]; // piece1
echo $pieces[1]; // piece2
// 例 2
$data = "foo:*:1023:1000::/home/foo:/bin/sh";
list($user, $pass, $uid, $gid, $gecos, $home, $shell) = explode(":", $data);
echo $user; // foo
echo $pass; // *
?>
例 2355. limit パラメータの例
<?php
$str = 'one|two|three|four';
// 正の値を持つ limit
print_r(explode('|', $str, 2));
// 負の値を持つ limit (PHP 5.1 以降)
print_r(explode('|', $str, -1));
?>
上の例の出力は以下となります。
Array
(
[0] => one
[1] => two|three|four
)
Array
(
[0] => one
[1] => two
[2] => three
)
注意: この関数はバイナリデータに対応しています。
preg_split(), str_split(), strtok(), implode(). も参照ください。
explode
26-Jul-2007 06:47
20-Jun-2007 09:28
While trying to use explode() to parse CSV formatted lines output by MS Excel, I found that if cells contained a comma, then explode() would not behave as desired. So I wrote the following function, which obeys the double quote escaping format output by Excel. Note that it is not sophisticated enough to handle delimiters or escapes that consist of more than one character. I also have no idea how this code will perform when subjected to Unicode data. Use at your own risk.
<?php
// splits a string into an array of tokens, delimited by delimiter char
// tokens in input string containing the delimiter character or the literal escape character are surrounded by a pair of escape characteres
// a literal escape character is produced by the escape character appearing twice in sequence
// default delimiter character and escape character are suitable for Excel-exported CSV formatted lines
function splitWithEscape ($str, $delimiterChar = ',', $escapeChar = '"') {
$len = strlen($str);
$tokens = array();
$i = 0;
$inEscapeSeq = false;
$currToken = '';
while ($i < $len) {
$c = substr($str, $i, 1);
if ($inEscapeSeq) {
if ($c == $escapeChar) {
// lookahead to see if next character is also an escape char
if ($i == ($len - 1)) {
// c is last char, so must be end of escape sequence
$inEscapeSeq = false;
} else if (substr($str, $i + 1, 1) == $escapeChar) {
// append literal escape char
$currToken .= $escapeChar;
$i++;
} else {
// end of escape sequence
$inEscapeSeq = false;
}
} else {
$currToken .= $c;
}
} else {
if ($c == $delimiterChar) {
// end of token, flush it
array_push($tokens, $currToken);
$currToken = '';
} else if ($c == $escapeChar) {
// begin escape sequence
$inEscapeSeq = true;
} else {
$currToken .= $c;
}
}
$i++;
}
// flush the last token
array_push($tokens, $currToken);
return $tokens;
}
?>
25-May-2007 11:49
@ tobylewis
No, it should not return a null array! The description clearly states: If delimiter contains a value that is not contained in string, then explode() will return an array containing string.
So it returns an array containing the original (empty) string.
Wouldn't you test for an invalid email address before trying to mail to it anyway? :S
25-May-2007 06:01
Watch out for this gottcha. Consider:
$arr = explode("/", "");
This should return a null array (ie count($arr) == 0).
Array
(
)
However, explode will instead return an array of one item which is a null string.
Array
(
[0] =>
)
There is some logic to the way this works but consider the following:
$addressees = "email@domain1.com, email@domain2.com";
$arr = explode(",", $addressees);
foreach($arr AS $to) mail ($to, $subject, $message);
with two items in the list it would sent two separate emails, with one it would sent one email message but with $addressees = "" it will still attempt to send one message that will fail because instead of returning an empty array explode returns an array with an empty item.
18-May-2007 12:45
@ JJ Rock, jason dot minett:
Here's an easy way around that:
<?php
$str = '^one^two^three^';
//Use trim() to remove extra delimiters
$arr = explode ('^', trim($str, '^'));
?>
27-Apr-2007 08:02
Just a quick note to compliment jason dot minett's comment a few down:
It's obvious that this works the opposite way as well:
<?php
$str = "^one^two^three";
$arr = explode ("^", $str);
?>
results in an empty value in $arr[0].
27-Apr-2007 06:08
<?php
// returns a string where $variables are replaced with their global value if available; removes all extra whitespaces
function evaluateString($string) {
if ($string) { // check for value
$array = explode(' ', $string); // split into parts
foreach ($array as $word) { // each part
if ($word[0] == '$') { // is part a variable
if ($word = substr($word, 1)) { // get variable name
global ${$word}; // retrieve global value
$html .= ${$word}; // add value to string
} // end variable name check
} else { // not a variable
$html .= $word; // add word to string
} // end variable check
$html .= ' '; // add space between words
} // end part loop
} // end string check
return trim($html); // trims final space from end
} // end evaluateString
?>
23-Apr-2007 10:43
of cause i ment the limit with my previouse post
@admin: wold u please change every "delimiter" in that post to "limit" and delete this note. thx.
23-Apr-2007 12:30
some more notes on the delimiter:
if the delimiter is 0, explode will return an array with one element containig the hole string (same as if the delimiter was 1).
if a negative delimiter is bigger or equal to the number of components, an empty array is returned.
<?php
print_r( explode( "|", "one|two|three|four", 0) );
print_r( explode( "|", "one|two|three|four", 1) );
?>
both print:
Array
(
[0] => one|two|tree|four
)
<?php
print_r( explode( "|", "one|two|three|four", -4) );
print_r( explode( "|", "one|two|three|four", -5) );
?>
both print:
Array
(
)
02-Mar-2007 01:09
A quick gotcha that had me head scratching for a while....
If the delimiter occurs right at the end of the string there will be an extra array element (an empty string):
<?php
$str = "aaa^elephant^chocolate^albatross^";
$arr = explode ("^", $str);
echo ("Array length: ".count($arr));
?>
---------------------------------
Array length: 5
28-Feb-2007 04:59
insensitive case explode function:
<?php
function iExplode($Delimiter, $String, $Limit = '')
{
$Explode = array();
$LastIni = 0;
$Count = 1;
if (is_numeric($Limit) == false)
$Limit = '';
while ( false !== ( $Ini = stripos($String, $Delimiter, $LastIni) ) && ($Count < $Limit || $Limit == ''))
{
$Explode[] = substr($String, $LastIni, $Ini-$LastIni);
$LastIni = $Ini+strlen($Delimiter);
$Count++;
}
$Explode[] = substr($String, $LastIni);
return $Explode;
}
?>
17-Dec-2006 02:28
A 'between' function that we've all been waiting for. I am not savvy with regex so I resorted to explode();
<?php
function between($beg, $end, $str) {
$a = explode($beg, $str, 2);
$b = explode($end, $a[1]);
return $beg . $b[0] . $end;
}
echo between('<a>', '</a>', 'fsdfsdfsd<a>fsdfsd<a><a></a>sdfsdfsdf')
//<a>fsdfsd<a><a></a>
?>
10-Dec-2006 12:49
Note that explode, split, and functions like it, can accept more than a single character for the delimiter.
<?php
$string = "Something--next--something else--next--one more";
print_r(explode('--next--',$string));
?>
21-Oct-2006 03:50
// simple function to remove words if more than max allowed words or add a charcter once less than min
// Example: LimitText("The red dog ran out of thefence",15,20,"<br>");
function LimitText($Text,$Min,$Max,$MinAddChar) {
if (strlen($Text) < $Min) {
$Limit = $Min-strlen($Text);
$Text .= $MinAddChar;
}
elseif (strlen($Text) >= $Max) {
$words = explode(" ", $Text);
$check=1;
while (strlen($Text) >= $Max) {
$c=count($words)-$check;
$Text=substr($Text,0,(strlen($words[$c])+1)*(-1));
$check++;
}
}
return $Text;
}
14-Mar-2006 03:20
If you want to split a price (float) into pounds and pence.
or dollors and cents etc etc.
$price = "6.20";
$split = explode(".", $price);
$pound = $split[0]; // piece1
$pence = $split[1]; // piece2
echo "£ $pound . $pence\n";
01-Dec-2004 09:50
Being a beginner in php but not so in Perl, I was used to split() instead of explode(). But as split() works with regexps it turned out to be much slower than explode(), when working with single characters.
24-Aug-2004 05:30
If you split an empty string, you get back a one-element array with 0 as the key and an empty string for the value.
<?php
$str = '';
$foo = explode( ":", $str );
print_r( $foo );
$foo = split( ":", $str );
print_r( $foo );
$foo = preg_split( "/:/", $str );
print_r( $foo );
?>
In all three cases prints
Array
(
[0] =>
)
This of course means that you must explicitly check to see if the value of the first element is blank, or must check to see if the string being split is blank.
17-Nov-2003 01:01
To split a string containing multiple seperators between elements rather use preg_split than explode:
preg_split ("/\s+/", "Here are to many spaces in between");
which gives you
array ("Here", "are", "to", "many", "spaces", "in", "between");