PHP
downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

数组> <浮点型
Last updated: Sun, 25 Nov 2007

view this page in

字符串

string 是一系列字符。在 PHP 中,字符和字节一样,也就是说,一共有 256 种不同字符的可能性。这也暗示 PHP 对 Unicode 没有本地支持。请参阅函数 utf8_encode()utf8_decode() 以了解有关 Unicode 支持。

Note: 一个字符串变得非常巨大也没有问题,PHP 没有给字符串的大小强加实现范围,所以完全没有理由担心长字符串。

语法

字符串可以用三种字面上的方法定义。

单引号

指定一个简单字符串的最简单的方法是用单引号(字符 ')括起来。

要表示一个单引号,需要用反斜线(\)转义,和很多其它语言一样。如果在单引号之前或字符串结尾需要出现一个反斜线,需要用两个反斜线表示。注意如果试图转义任何其它字符,反斜线本身也会被显示出来!所以通常不需要转义反斜线本身。

Note: 在 PHP 3 中,此情况下将发出一个 E_NOTICE 级的警告。

Note: 和其他两种语法不同,单引号字符串中出现的变量和转义序列不会被变量的值替代。

<?php
echo 'this is a simple string';

echo 
'You can also have embedded newlines in
strings this way as it is
okay to do'
;

// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?';

// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline';

// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either';
?>

双引号

如果用双引号(")括起字符串,PHP 懂得更多特殊字符的转义序列:

转义字符
序列 含义
\n 换行(LF 或 ASCII 字符 0x0A(10))
\r 回车(CR 或 ASCII 字符 0x0D(13))
\t 水平制表符(HT 或 ASCII 字符 0x09(9))
\\ 反斜线
\$ 美元符号
\" 双引号
\[0-7]{1,3} 此正则表达式序列匹配一个用八进制符号表示的字符
\x[0-9A-Fa-f]{1,2} 此正则表达式序列匹配一个用十六进制符号表示的字符

此外,如果试图转义任何其它字符,反斜线本身也会被显示出来!在 PHP 5.1.1 之前,\{$var} 中的反斜线不会被显示出来。

双引号字符串最重要的一点是其中的变量名会被变量值替代。细节参见字符串解析

定界符

另一种给字符串定界的方法使用定界符语法(“<<<”)。应该在 <<< 之后提供一个标识符,然后是字符串,然后是同样的标识符结束字符串。

结束标识符必须从行的第一列开始。同样,标识符也必须遵循 PHP 中其它任何标签的命名规则:只能包含字母数字下划线,而且必须以下划线或非数字字符开始。

Warning

很重要的一点必须指出,结束标识符所在的行不能包含任何其它字符,可能除了一个分号(;)之外。这尤其意味着该标识符不能被缩进,而且在分号之前和之后都不能有任何空格或制表符。同样重要的是要意识到在结束标识符之前的第一个字符必须是你的操作系统中定义的换行符。例如在 Macintosh 系统中是 \r

如果破坏了这条规则使得结束标识符不“干净”,则它不会被视为结束标识符,PHP 将继续寻找下去。如果在这种情况下找不到合适的结束标识符,将会导致一个在脚本最后一行出现的语法错误。

不能用定界符语法初始化类成员。用其它字符串语法替代。

Example#1 非法的例子

<?php
class foo {
    public 
$bar = <<<EOT
bar
EOT;
}
?>

定界符文本表现的就和双引号字符串一样,只是没有双引号。这意味着在定界符文本中不需要转义引号,不过仍然可以用以上列出来的转义代码。变量会被展开,但当在定界符文本中表达复杂变量时和字符串一样同样也要注意。

Example#2 定界符字符串例子

<?php
$str 
= <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* More complex example, with variables. */
class foo
{
    var 
$foo;
    var 
$bar;

    function 
foo()
    {
        
$this->foo 'Foo';
        
$this->bar = array('Bar1''Bar2''Bar3');
    }
}

$foo = new foo();
$name 'MyName';

echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some 
{$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>

Note: 定界符支持是 PHP 4 中加入的。

变量解析

当用双引号或者定界符指定字符串时,其中的变量会被解析。

有两种语法,一种简单的和一种复杂的。简单语法最通用和方便,它提供了解析变量,数组值,或者对象属性的方法。

复杂语法是 PHP 4 引进的,可以用花括号括起一个表达式。

简单语法

如果遇到美元符号($),解析器会尽可能多地取得后面的字符以组成一个合法的变量名。如果想明示指定名字的结束,用花括号把变量名括起来。

<?php
$beer 
'Heineken';
echo 
"$beer's taste is great"// works, "'" is an invalid character for varnames
echo "He drank some $beers";   // won't work, 's' is a valid character for varnames
echo "He drank some ${beer}s"// works
echo "He drank some {$beer}s"// works
?>

同样也可以解析数组索引或者对象属性。对于数组索引,右方括号(])标志着索引的结束。对象属性则和简单变量适用同样的规则,尽管对于对象属性没有像变量那样的小技巧。

<?php
// These examples are specific to using arrays inside of strings.
// When outside of a string, always quote your array string keys
// and do not use {braces} when outside of strings either.

// Let's show all errors
error_reporting(E_ALL);

$fruits = array('strawberry' => 'red''banana' => 'yellow');
// Works but note that this works differently outside string-quotes
echo "A banana is $fruits[banana].";
// Works
echo "A banana is {$fruits['banana']}.";

// Works but PHP looks for a constant named banana first
// as described below.
echo "A banana is {$fruits[banana]}.";

// Won't work, use braces.  This results in a parse error.
echo "A banana is $fruits['banana'].";

// Works
echo "A banana is " $fruits['banana'] . ".";

// Works

echo "This square is $square->width meters broad.";
// Won't work. For a solution, see the complex syntax.
echo "This square is $square->width00 centimeters broad.";
?>

对于任何更复杂的情况,应该使用复杂语法。

复杂(花括号)语法

不是因为语法复杂而称其为复杂,而是因为用此方法可以包含复杂的表达式。

事实上,用此语法可以在字符串中包含任何在名字空间的值。仅仅用和在字符串之外同样的方法写一个表达式,然后用 { 和 } 把它包含进来。因为不能转义“{”,此语法仅在 $ 紧跟在 { 后面时被识别(用“{\$”来得到一个字面上的“{$”)。用一些例子可以更清晰:

<?php
// Let's show all errors
error_reporting(E_ALL);

$great 'fantastic';

// 不行,输出为:This is { fantastic}
echo "This is { $great}";

// 可以,输出为:This is fantastic
echo "This is {$great}";
echo 
"This is ${great}";

// Works
echo "This square is {$square->width}00 centimeters broad.";

// Works
echo "This works: {$arr[4][3]}";
// This is wrong for the same reason as $foo[bar] is wrong
// outside a string.  In otherwords, it will still work but
// because PHP first looks for a constant named foo, it will
// throw an error of level E_NOTICE (undefined constant).
echo "This is wrong: {$arr[foo][3]}";
// Works.  When using multi-dimensional arrays, always use
// braces around arrays when inside of strings
echo "This works: {$arr['foo'][3]}";

// Works.
echo "This works: " $arr['foo'][3];

echo 
"You can even write {$obj->values[3]->name}";

echo 
"This is the value of the var named $name: {${$name}}";
?>

访问和修改字符串中的字符

字符串中的字符可以通过在字符串之后用花括号指定所要字符从零开始的偏移量来访问和修改。

Note: 为了向下兼容,仍然可以用方括号。不过此语法自 PHP 4 起已过时。

Example#3 一些字符串例子

<?php
// Get the first character of a string
$str 'This is a test.';
$first $str{0};
// Get the third character of a string
$third $str{2};

// Get the last character of a string.
$str 'This is still a test.';
$last $str{strlen($str)-1};

// Modify the last character of a string
$str 'Look at the sea';
$str{strlen($str)-1} = 'e';

?>

实用函数及运算符

字符串可以用“.”(点)运算符连接。注意这里不能用“+”(加)运算符。更多信息参见字符串运算符

有很多实用函数来改变字符串。

普通函数见字符串函数一节,高级搜索和替换见正则表达式函数(两种风格:PerlPOSIX 扩展)。

还有 URL 字符串函数,以及加密/解密字符串的函数(mcryptmhash)。

最后,如果还是找不到想要的函数,参见字符类型函数

字符串转换

可以用 (string) 标记或者 strval() 函数将一个值转换为字符串。当某表达式需要字符串时,字符串的转换会在表达式范围内自动完成。例如当使用 echo() 或者 print() 函数时,或者将一个变量值与一个字符串进行比较的时候。阅读手册中有关类型类型戏法中的部分有助于更清楚一些。参见 settype()

布尔值 TRUE 将被转换为字符串 "1",而值 FALSE 将被表示为 ""(即空字符串)。这样就可以随意地在布尔值和字符串之间进行比较。

整数或浮点数数值在转换成字符串时,字符串由表示这些数值的数字字符组成(浮点数还包含有指数部分)。

数组将被转换成字符串 "Array",因此无法通过 echo() 或者 print() 函数来输出数组的内容。请参考下文以获取更多提示。

对象将被转换成字符串 "Object"。如果因为调试需要,需要将对象的成员变量打印出来,请阅读下文。如果希望得到该对象所依附的类的名称,请使用函数 get_class()。自 PHP 5 起,如果合适可以用 __toString() 方法。

资源类型总是以 "Resource id #1" 的格式被转换成字符串,其中 1 是 PHP 在运行时给资源指定的唯一标识。如果希望获取资源的类型,请使用函数 get_resource_type()

NULL 将被转换成空字符串。

正如以上所示,将数组、对象或者资源打印出来,并不能提供任何关于这些值本身的有用的信息。请参阅函数 print_r()var_dump(),对于调试来说,这些是更好的打印值的方法。

可以将 PHP 的值转换为字符串以永久地储存它们。这种方法被称为序列化,可以用函数 serialize() 来完成该操作。如果在安装 PHP 时建立了 WDDX 支持,还可以将 PHP 的值序列化为 XML 结构。

字符串转换为数值

当一个字符串被当作数字来求值时,根据以下规则来决定结果的类型和值。

如果包括“.”,“e”或“E”其中任何一个字符的话,字符串被当作 float 来求值。否则就被当作整数。

该值由字符串最前面的部分决定。如果字符串以合法的数字数据开始,就用该数字作为其值,否则其值为 0(零)。合法数字数据由可选的正负号开始,后面跟着一个或多个数字(可选地包括十进制分数),后面跟着可选的指数。指数是一个“e”或者“E”后面跟着一个或多个数字。

<?php
$foo 
"10.5";                // $foo is float (11.5)
$foo "-1.3e3";              // $foo is float (-1299)
$foo "bob-1.3e3";           // $foo is integer (1)
$foo "bob3";                // $foo is integer (1)
$foo "10 Small Pigs";       // $foo is integer (11)
$foo "10.2 Little Piggies"// $foo is float (14.2)
$foo "10.0 pigs " 1;          // $foo is float (11)
$foo "10.0 pigs " 1.0;        // $foo is float (11)
?>

此转换的更多信息见 Unix 手册中关于 strtod(3) 的部分。

如果想测试本节中的任何例子,可以拷贝和粘贴这些例子并且加上下面这一行自己看看会发生什么:

<?php
echo "\$foo==$foo; type is " gettype ($foo) . "<br />\n";
?>

不要指望在将一个字符转换成整型时能够得到该字符的编码(可能也会在 C 中这么做)。如果希望在字符编码和字符之间转换,请使用 ord()chr() 函数。



数组> <浮点型
Last updated: Sun, 25 Nov 2007
 
add a note add a note User Contributed Notes
字符串
headden at karelia dot ru
20-Jun-2009 07:43
Here is an easy hack to allow double-quoted strings and heredocs to contain arbitrary expressions in curly braces syntax, including constants and other function calls:

<?php

// Hack declaration
function _expr($v) { return $v; }
$_expr = '_expr';

// Our playground
define('qwe', 'asd');
define('zxc', 5);

$a=3;
$b=4;

function
c($a, $b) { return $a+$b; }

// Usage
echo "pre {$_expr(1+2)} post\n"; // outputs 'pre 3 post'
echo "pre {$_expr(qwe)} post\n"; // outputs 'pre asd post'
echo "pre {$_expr(c($a, $b)+zxc*2)} post\n"; // outputs 'pre 17 post'

// General syntax is {$_expr(...)}
?>
strata_ranger at hotmail dot com
12-Apr-2009 12:31
A limitation of the 'complex' parsing of double-quoted strings (i.e. with curly braces) is that since you can't escape curly braces, if for some reason you need a parsed variable surrounded by literal curly braces, you can't do this directly.

For example, say want to dynamically compile some Javascript for the client's browser:

<?php

// Here's the array we start with.
$array = Array(0=>'foo', 1=>'bar');

// This is how the same array would look in Javascript:
//   var my_array = {0:'foo', 1:'bar'}

// This is how we'll convert it to the Javascript representation
$values = Array();
foreach(
$array as $key=>$string) $values[] = sprintf("%d:'%s'", $key, addcslashes($string, "'"));
$values = implode(',' , $values); // $values is now = "0:'foo', 1:'bar'"

// Begin echoing the Javascript
echo "<script type='text/javascript'>";

// This works
echo 'var my_array = {' . $values .'}'; // outputs: var my_array {0:'foo', 1:'bar'}

// This also works (note the spaces, we want the curly braces to be taken literally).
echo "var my_array = { $values }"; // outputs: var my_array = { 0:'foo', 1:'bar' }

// Doesn't work, the curly-braces get parsed and in this case we actually don't want that
echo "var my_array = {$values}"; // outputs: var my_array = 0:'foo', 1:'bar'

// Obviously doesn't work -- we need $values to be parsed
echo "var my_array = {\$values}"; // outputs: var my_array = {$values}

// Doesn't work -- { can't be escaped
echo "var my_array = \{$values}"; // outputs: var my_array \0:'foo', 1:'bar'

// But using ASCII values works
echo "var my_array = \x7B$values\x7D"; // outputs: var my_array = {0:'foo', 1:'bar'}
?>

The simplest solution in this example is to separate the { from the $ using whitespace.
Jarobman
21-Mar-2009 09:20
One thing I have noticed (using PHP 5.2.4) is that alphanumeric text starting with letters or underscore without spaces and operators in PHP code without single or double quotes is interpreted as a string.  I noticed this when trying to access a member variable from an object and getting an integer returned on what I thought should have been a syntax error.  The text cannot correspond to most PHP keywords since that would generate a fatal error.

<?php
class MyObject
{
    private
$__internal_array = array();
   
//insert code for overloading __get(), __set(), etc. to
    //access items from $__internal_array
}

$object = new MyObject();

//thought this would give a syntax error, put param returned an int somehow
some_function($object-membervar);

//correct
echo hiImAString;

//correct
echo hello.world._6789;

//correct
thisisastandalonestring;

//correct, outputs 0
echo string+anotherstring-yetanotherstring;

//correct, outputs 1concatenated
echo true.false.concatenated;

//incorrect, syntax error
echo cantdothis.1234567890;

//incorrect, syntax error, use of PHP keywords
echo try.and.do.this.if.you.can.else.break;
?>

Any other combination of the above with operators and other special characters will generate fatal errors.  I think it would be the opinion of many people that this form of a string is not at all practical and should never be used at all.  Personally, I think this looks like a bug, but I could be wrong.  However, this is something else one could watch out for when debugging since this is hard to pick up in code especially when expecting integer or boolean values.

Cheers,
Jarobman
cvolny at gmail dot com
03-Dec-2008 07:43
I commented on a php bug feature request for a string expansion function and figured I should post somewhere it might be useful:

using regex, pretty straightforward:
<?php
function stringExpand($subject, array $vars) {
   
// loop over $vars map
   
foreach ($vars as $name => $value) {
       
// use preg_replace to match ${`$name`} or $`$name`
       
$subject = preg_replace(sprintf('/\$\{?%s\}?/', $name), $value,
$subject);
    }
   
// return variable expanded string
   
return $subject;
}
?>

using eval() and not limiting access to only certain variables (entire current symbol table including [super]globals):

<?php
function stringExpandDangerous($subject, array $vars = array(), $random = true) {
   
       
// extract $vars into current symbol table
       
extract($vars);
       
       
$delim;
       
// if requested to be random (default), generate delim, otherwise use predefined (trivially faster)
       
if ($random)
           
$delim = '___' . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . '___';
        else
           
$delim = '__ASDFZXCV1324ZXCV__'// button mashing...
       
        // built the eval code
       
$statement = "return <<<$delim\n\n" . $subject . "\n$delim;\n";
       
       
// execute statement, saving output to $result variable
       
$result = eval($statement);
       
       
// if eval() returned FALSE, throw a custom exception
       
if ($result === false)
            throw new
EvalException($statement);
       
       
// return variable expanded string
       
return $result;
    }
?>

I hope that helps someone, but I do caution against using the eval() route even if it is tempting.  I don't know if there's ever a truely safe way to use eval() on the web, I'd rather not use it.
Obeliks
16-Nov-2008 04:21
Expectedly <?php $string[$x] ?> and <?php substr($string, $x, 1) ?> will yield the same result... normally!

However, when you turn on the  Function Overloading Feature (http://de.php.net/manual/en/mbstring.overload.php), this might not be true!

If you use this Overloading Feature with 3rd party software, you should check for usage of the String access operator, otherwise you might be in for some nasty surprises.
Salil Kothadia
15-Oct-2008 08:33
An interesting finding about Heredoc "syntax error, unexpected $end".
I got this error because I did not use the php close tag "?>" and I had no code after the heredoc code.

foo1.php code gives "syntax error, unexpected $end".
But in foo2.php and foo3.php, when you add a php close tag or when you have some more code after heredoc it works fine.

Example Code:
foo1.php
1. <?php
2. $str
= <<<EOD
3. Example of string
4. spanning multiple lines
5. using heredoc syntax.
6. EOD;
7.

foo2.php
1. <?php
2. $str = <<<EOD
3. Example of string
4. spanning multiple lines
5. using heredoc syntax.
6. EOD;
7.
8. echo $str;
9.

foo3.php
1. <?php
2. $str = <<<EOD
3. Example of string
4. spanning multiple lines
5. using heredoc syntax.
6. EOD;
7. ?>
steve at mrclay dot org
30-Sep-2008 08:33
Simple function to create human-readably escaped double-quoted strings for use in source code or when debugging strings with newlines/tabs/etc.

<?php
function doubleQuote($str) {
   
$ret = '"';
    for (
$i = 0, $l = strlen($str); $i < $l; ++$i) {
       
$o = ord($str[$i]);
        if (
$o < 31 || $o > 126) {
            switch (
$o) {
                case
9: $ret .= '\t'; break;
                case
10: $ret .= '\n'; break;
                case
11: $ret .= '\v'; break;
                case
12: $ret .= '\f'; break;
                case
13: $ret .= '\r'; break;
                default:
$ret .= '\x' . str_pad(dechex($o), 2, '0', STR_PAD_LEFT);
            }
        } else {
            switch (
$o) {
                case
36: $ret .= '\$'; break;
                case
34: $ret .= '\"'; break;
                case
92: $ret .= '\\\\'; break;
                default:
$ret .= $str[$i];
            }
        }
    }
    return
$ret . '"';
}
?>
chAlx at findme dot if dot u dot need
11-Sep-2008 03:42
To save Your mind don't read previous comments about dates  ;)

When both strings can be converted to the numerics (in ("$a" > "$b") test) then resulted numerics are used, else FULL strings are compared char-by-char:

<?php
var_dump
('1.22' > '01.23'); // bool(false)
var_dump('1.22.00' > '01.23.00'); // bool(true)
var_dump('1-22-00' > '01-23-00'); // bool(true)
var_dump((float)'1.22.00' > (float)'01.23.00'); // bool(false)
?>
harmor
01-Sep-2008 10:05
So you want to get the last character of a string using "String access and modification by character"?  Well negative indexes are not allowed so $str[-1] will return an empty string.

<?php
//Tested using: PHP 5.2.5

$str = 'This is a test.';

$last = $str[-1];                  //string(0) ""
$realLast = $str[strlen($str)-1];  //string(1) "."
$substr = substr($str,-1);         //string(1) "."

echo '<pre>';
var_dump($last);
var_dump($realLast);
var_dump($substr);
nullhility at gmail dot com
06-Jun-2008 07:40
It's also valuable to note the following:

<?php
${date("M")} = "Worked";
echo ${
date("M")};
?>

This is perfectly legal, anything inside the braces is executed first, the return value then becomes the variable name. Echoing the same variable variable using the function that created it results in the same return and therefore the same variable name is used in the echo statement. Have fun ;).
sk89q
30-Apr-2008 07:46
<?php
$F
= "F";
function
F($s) { return $s; }
$filename = '<some code>';
echo
"{$F(htmlspecialchars($filename))}";
?>
yuku
01-Apr-2008 02:21
This example of the heredoc has wrong output:
Code: This should print a capital 'A': \x41
Output should be: This should print a capital 'A': A

The example of the nowdoc has wrong code:
Code: This should not print a capital 'A': x41
That should be: This should not print a capital 'A': \x41
chris at chrisstockton dot org
24-Mar-2008 02:58
For anyone who reads Evan K, please note that:
// a string to test, and show the before and after
$before = 'Quantity:\t500\nPrice:\t$5.25 each';
$after = expand_escape($before);
var_dump($before, $after);

Is identical to (note all I added was a backslash before $):
$before = "Quantity:\t500\nPrice:\t\$5.25 each";
var_dump($before);

So its definitely better to escape a dollar instead of all the overhead of his regex and evals and such, although clever completely unnecessary.

-Chris
Evan K
28-Feb-2008 09:03
I encountered the odd situation of having a string containing unexpanded escape sequences that I wanted to expand, but also contained dollar signs that would be interpolated as variables.  "$5.25\n", for example, where I want to convert \n to a newline, but don't want attempted interpolation of $5.

Some muddling through docs and many obscenties later, I produced the following, which expands escape sequences in an existing string with NO interpolation.

<?php

// where we do all our magic
function expand_escape($string) {
    return
preg_replace_callback(
       
'/\\\([nrtvf]|[0-7]{1,3}|[0-9A-Fa-f]{1,2})?/',
       
create_function(
           
'$matches',
           
'return ($matches[0] == "\\\\") ? "" : eval( sprintf(\'return "%s";\', $matches[0]) );'
       
),
       
$string
   
);
}

// a string to test, and show the before and after
$before = 'Quantity:\t500\nPrice:\t$5.25 each';
$after = expand_escape($before);
var_dump($before, $after);

/* Outputs:
string(34) "Quantity:\t500\nPrice:\t$5.25 each"
string(31) "Quantity:    500
Price:    $5.25 each"
*/

?>
dot dot dot dot dot alexander at gmail dot com
07-Feb-2008 06:31
I think there's not that much to string comparison as claiming date recognition:

It's simply comparing ordinal values of the characters from the {0} to the {strlen-1} one.
In this case
<?php
$a
= '2007-11-06 15:17:48';
$b = '2007-11-05 15:17:48';

var_dump($a > $b);
?>
mArIo@luigi ~ $: php test.php
bool(true)
here all characters match till it reaches position 9 (the "day")
there, 6 has a bigger ord()inal value than 5

<?php
$a
= 'January 25th, 2008 00:23:38';
$b = 'Janury 24th, 2008 00:23:37'; // ($a > $b) === false
?>
Here when we reach 'r' in "Janury" we see that "a" is "less" than "r" so the example would evaluate as ($a < $b) === true

Here:
<?php
$a
= 'February 1st, 2008 00:23:38';
$b = 'January 25th, 2008 00:23:38';
?>
as expected the letter "F" comes before "J" as an ordinal character, so $a is less than $b
 Even here:
<?php
var_dump
('Z' > 'M'); //bool(true)
?>
it gets confirmed that the string comparison operators >, <, =>, =<, == just do a ordinal character comparison starting from position {0} to the first difference or the end of the string.
topnotcher at mail dot uri dot edu
28-Jan-2008 04:25
@qriz at example dot com

Numerical comparisons, such as <, > are simply _NOT_ valid on strings.  Thus, before a comparison can be made by a numerical comparison operator, the operands must be _casted_ to a numerical type (either float or int).  What I was attempting to say in my previous post is that >, < are date-aware; the tests I included were examples, and not intended to represent the full scope of my comparison.

"Works correctly since there is a comparing between strings. The comparisson is done on the last number/letter (since thats the only thing that is difference in the string) and that is in this case: the 9 and 8."

What you say here is mere assumption; a few quick tests show that this is indeed not the case.  If PHP indeed compares only the last character in the string, then the following assertion should be false:

test.php:
<?php
$a
= '2007-11-06 15:17:48';
$b = '2007-11-05 15:17:48';

var_dump($a > $b);
?>
mArIo@luigi ~ $: php test.php
bool(true)

Further, consider the following choices for $a and $b, which, as expected, demonstrate that the <, > operators can indeed understand date formats:

<?php
$a
= 'January 25th, 2008 00:23:37';
$b = 'January 24th, 2008 00:23:38'; // ($a > $b) === true, but 8
?>

If you remain unconvinced, consider what happens if I spell January incorrectly:

<?php
$a
= 'January 25th, 2008 00:23:38';
$b = 'Janury 24th, 2008 00:23:37'; // ($a > $b) === false
?>

Looks like it can understand ISO 8601 date formats? (for more information, see http://en.wikipedia.org/wiki/ISO_8601)

Further investigation yields that this doesn't even work as it should:
<?php
$a
= 'February 1st, 2008 00:23:38';
$b = 'January 25th, 2008 00:23:38';

var_dump($a > $b); //bool(false)

var_dump(strtotime($a)); //int(1201843418)
var_dump(strtotime($b)); //int(1201238618)
var_dump(strtotime($a) - strtotime($b)); //int(604800)
?>
Keeping $b constant and varying the month in $a shows that this comparison correctly interprets the date with the following months: January,March,May,June,July,September,October,November.  Interestingly enough, these are all the months having the property that ord($a[0]) >= ord($b[0]).

<?php
var_dump
('Z' > 'M'); //bool(true)
?>

Conclusion:
The <,> comparison operators definitely have functionality that is undocumented, including date awareness; however, this functionality may not always work as expected and should not be trusted for portability.
yuchunjiang at gmail dot com
23-Jan-2008 02:38
this is the sql string that use the variable and and \' and function.It generate the correct result.
 
$sql1=<<<EOT
INSERT INTO hp_visitHistory ( col1,col2,col3)
VALUES ( NOW(), '{$col2}', '{$_SERVER['REQUEST_URI']}')
EOT;
echo $sql1;
qriz at example dot com
13-Nov-2007 05:54
<?php
$a
= '2007-11-05 15:17:49';
$b = '2007-11-05 15:17:48';

$bool = $a > $b;

var_dump($bool); //bool(true)
?>

works correctly since there is a comparing between strings. The comparisson is done on the last number/letter (since thats the only thing that is difference in the string) and that is in this case: the 9 and 8.

8 > 9 = true

if you want to compare the string as pure numbers then you must type cast it to numbers or type juggle it:

<?php
$a
= '2007-11-05 15:17:49';
$b = '2007-11-05 15:17:48';

$bool1 = ($a + 0) > ($b + 0);      // 2007 > 2007
$bool2 = (int) $a > (int) $b;        // 2007 > 2007
$bool3 = intval($a) > intval($b);  // 2007 > 2007

var_dump($bool1,$bool2,$bool3); //bool(false)
?>
topnotcher at mail dot uri dot edu
06-Nov-2007 12:48
I have come across this several times, and as far as I can tell, the < and > operators have undocumented functionality when it comes to comparing strings.  Consider the following script:

<?php
$a
= '2007-11-05 15:17:49';
$b = '2007-11-05 15:17:48';

$bool = $a > $b;

var_dump($bool); //bool(true)

/**
 * The manual tells us that $a and $b should be
 * truncated at -, thus giving a floating-point value of 2007.
 * But (2007 > 2007) === false...
 */
$a = (float)$a;
$b = (float)$b;

var_dump($a); //float(2007);
var_dump($b); //float(2007);

/**
 * And the manual is right. So why does it correctly
 * compare the dates (which should be treated
 * as normal strings? Clearly some hidden functionality...
 */
rkfranklin+php at gmail dot com
26-Sep-2007 07:35
If you want to use a variable in an array index within a double quoted string you have to realize that when you put the curly braces around the array, everything inside the curly braces gets evaluated as if it were outside a string.  Here are some examples:

<?php
$i
= 0;
$myArray[Person0] = Bob;
$myArray[Person1] = George;

// prints Bob (the ++ is used to emphasize that the expression inside the {} is really being evaluated.)
echo "{$myArray['Person'.$i++]}<br>";

// these print George
echo "{$myArray['Person'.$i]}<br>";
echo
"{$myArray["Person{$i}"]}<br>";

// These don't work
echo "{$myArray['Person$i']}<br>";
echo
"{$myArray['Person'$i]}<br>";

// These both throw fatal errors
// echo "$myArray[Person$i]<br>";
//echo "$myArray[Person{$i}]<br>";
?>
michael at mahemoff dot com
07-Jul-2007 07:51
Heredocs can be used for more than just echoing or setting variables - use them whenever you want to include a string.

function header() {
  return <<<EOT
    <html>
      <head>
        <title>This is my heredoc</title>
      </head>
      <body>
EOT;

Also, note the strict syntax:
- No semicolon after initial EOT (think of the heredoc as a literal string arg - you wouldn't want a semicolon in front of it, would you?)
- BUT need semicolon after final EOT (the command is finished here)
- Final EOT is on the left margin - don't indent it!
php at craigbuchek dot com
03-Jul-2007 09:32
Function calls within double-quote variable interpolation work in PHP 5, but not quite as you'd expect. Basically the function has to be a variable function. I.e. a variable that holds the name of a function. So if you've got a function named 'x' that you want to call, you'll have to assign the function name to a variable. It's easiest to just assign it to a variable with the same name:

function x () { return 4; }
$x = 'x';
echo "x = {$x()}";

I'm not sure what the point of that is though, since it would be easier to do it this way:

function x () { return 4; }
$x = x();
echo "x = $x";
Richard Neill
01-Jun-2007 03:31
Unlike bash, we can't do
  echo "\a"       #beep!

Of course, that would be rather meaningless for PHP/web, but it's useful for PHP-CLI. The solution is simple:  echo "\x07"
og at gams dot at
26-Apr-2007 12:06
easy transparent solution for using constants in the heredoc format:
DEFINE('TEST','TEST STRING');

$const = get_defined_constants();

echo <<<END
{$const['TEST']}
END;

Result:
TEST STRING
penda ekoka
24-Apr-2007 05:14
error control operator (@) with heredoc syntax:

the error control operator is pretty handy for supressing minimal errors or omissions. For example an email form that request some basic non mandatory information to your users. Some may complete the form, other may not. Lets say you don't want to tweak PHP for error levels and you just wish to create some basic template that will be emailed to the admin with the user information submitted. You manage to collect the user input in an array called $form:

<?php
// creating your mailer
$mailer = new SomeMailerLib();
$mailer->from = ' System <mail@yourwebsite.com>';
$mailer->to = 'admin@yourwebsite.com';
$mailer->subject = 'New user request';
// you put the error control operator before the heredoc operator to suppress notices and warnings about unset indices like this
$mailer->body = @<<<FORM
Firstname = {$form['firstname']}
Lastname =
{$form['lastname']}
Email =
{$form['email']}
Telephone =
{$form['telephone']}
Address =
{$form['address']}
FORM;

?>
php at moechofe dot com
01-Apr-2007 03:44
A simple benchmark to check differents about :
- simple and double quote concatenation and
- double quote and heredoc replacement

<?php

function test_simple_quote_concat()
{
 
$b = 'string';
 
$a  = ' string'.$b.' string'.$b.' srting'.$b;
 
$a .= ' string'.$b.' string'.$b.' string'.$b;
 
$a .= ' string'.$b.' string'.$b.' string'.$b;
 
$a .= ' string'.$b.' string'.$b.' string'.$b;
 
$a .= ' string'.$b.' string'.$b.' string'.$b;
 
$a .= ' string'.$b.' string'.$b.' string'.$b;
 
$a .= ' string'.$b.' string'.$b.' string'.$b;
 
$a .= ' string'.$b.' string'.$b.' string'.$b;
}

function
test_double_quote_concat()
{
 
$b = "string";
 
$a  = " string".$b." string".$b." string".$b;
 
$a .= " string".$b." string".$b." string".$b;
 
$a .= " string".$b." string".$b." string".$b;
 
$a .= " string".$b." string".$b." string".$b;
 
$a .= " string".$b." string".$b." string".$b;
 
$a .= " string".$b." string".$b." string".$b;
 
$a .= " string".$b." string".$b." string".$b;
 
$a .= " string".$b." string".$b." string".$b;
}

function
test_double_quote_replace()
{
 
$b = "string";
 
$a = " string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b"
;
}

function
test_eot_replace()
{
 
$b = <<<EOT
string
EOT;
 
$a = <<<EOT
string{$b} string{$b} string{$b}
string
{$b} string{$b} string{$b}
string
{$b} string{$b} string{$b}
string
{$b} string{$b} string{$b}
string
{$b} string{$b} string{$b}
string
{$b} string{$b} string{$b}
string
{$b} string{$b} string{$b}
string
{$b} string{$b} string{$b}
EOT;
}

$iter = 2000;

for(
$i=0; $i<$iter; $i++ )
 
test_simple_quote_concat();

for(
$i=0; $i<$iter; $i++ )
 
test_double_quote_concat();

for(
$i=0; $i<$iter; $i++ )
 
test_double_quote_replace();

for(
$i=0; $i<$iter; $i++ )
 
test_eot_replace();

?>

I've use xdebug profiler to obtain the followed results:

test_simple_quote_concat : 173ms
test_double_quote_concat : 161ms
test_double_quote_replace : 147ms
test_eot_replace : 130ms
bryant at zionprogramming dot com
27-Feb-2007 08:16
As of (at least) PHP 5.2, you can no longer convert an object to a string unless it has a __toString method. Converting an object without this method now gives the error:

PHP Catchable fatal error:  Object of class <classname> could not be converted to string in <file> on line <line>

Try this code to get the same results as before:

<?php

if (!is_object($value) || method_exists($value, '__toString')) {
   
$string = (string)$value;
} else {
   
$string = 'Object';
}

?>
fmouse at fmp dot com
21-Feb-2007 06:20
It may be obvious to some, but it's convenient to note that variables _will_ be expanded inside of single quotes if these occur inside of a double-quoted string.  This can be handy in constructing exec calls with complex data to be passed to other programs.  e.g.:

$foo = "green";
echo "the grass is $foo";
the grass is green

echo 'the grass is $foo';
the grass is $foo

echo "the grass is '$foo'";
the grass is 'green'
bishop
28-Mar-2006 08:58
You may use heredoc syntax to comment out large blocks of code, as follows:
<?php
<<<_EOC
    // end-of-line comment will be masked... so will regular PHP:
    echo ($test == 'foo' ? 'bar' : 'baz');
    /* c-style comment will be masked, as will other heredocs (not using the same marker) */
    echo <<<EOHTML
This is text you'll never see!       
EOHTML;
    function defintion($params) {
        echo 'foo';
    }
    class definition extends nothing     {
       function definition($param) {
          echo 'do nothing';
       }      
    }

    how about syntax errors?; = gone, I bet.
_EOC;
?>

Useful for debugging when C-style just won't do.  Also useful if you wish to embed Perl-like Plain Old Documentation; extraction between POD markers is left as an exercise for the reader.

Note there is a performance penalty for this method, as PHP must still parse and variable substitute the string.
webmaster at rephunter dot net
30-Nov-2005 04:57
Use caution when you need white space at the end of a heredoc. Not only is the mandatory final newline before the terminating symbol stripped, but an immediately preceding newline or space character is also stripped.

For example, in the following, the final space character (indicated by \s -- that is, the "\s" is not literally in the text, but is only used to indicate the space character) is stripped:

$string = <<<EOT
this is a string with a terminating space\s
EOT;

In the following, there will only be a single newline at the end of the string, even though two are shown in the text:

$string = <<<EOT
this is a string that must be
followed by a single newline

EOT;
DELETETHIS dot php at dfackrell dot mailshell dot com
01-Nov-2005 04:05
Just some quick observations on variable interpolation:

Because PHP looks for {? to start a complex variable expression in a double-quoted string, you can call object methods, but not class methods or unbound functions.

This works:

<?php
class a {
    function
b() {
        return
"World";
    }
}
$c = new a;
echo
"Hello {$c->b()}.\n"
?>

While this does not:

<?php
function b() {
    return
"World";
}
echo
"Hello {b()}\n";
?>

Also, it appears that you can almost without limitation perform other processing within the argument list, but not outside it.  For example:

<?
$true
= true;
define("HW", "Hello World");
echo
"{$true && HW}";
?>

gives: Parse error: parse error, unexpected T_BOOLEAN_AND, expecting '}' in - on line 3

There may still be some way to kludge the syntax to allow constants and unbound function calls inside a double-quoted string, but it isn't readily apparent to me at the moment, and I'm not sure I'd prefer the workaround over breaking out of the string at this point.
lelon at lelon dot net
27-Oct-2004 07:01
You can use the complex syntax to put the value of both object properties AND object methods inside a string.  For example...
<?php
class Test {
    public
$one = 1;
    public function
two() {
        return
2;
    }
}
$test = new Test();
echo
"foo {$test->one} bar {$test->two()}";
?>
Will output "foo 1 bar 2".

However, you cannot do this for all values in your namespace.  Class constants and static properties/methods will not work because the complex syntax looks for the '$'.
<?php
class Test {
    const
ONE = 1;
}
echo
"foo {Test::ONE} bar";
?>
This will output "foo {Test::one} bar".  Constants and static properties require you to break up the string.
Jonathan Lozinski
06-Aug-2004 07:03
A note on the heredoc stuff.

If you're editing with VI/VIM and possible other syntax highlighting editors, then using certain words is the way forward.  if you use <<<HTML for example, then the text will be hightlighted for HTML!!

I just found this out and used sed to alter all EOF to HTML.

JAVASCRIPT also works, and possibly others.  The only thing about <<<JAVASCRIPT is that you can't add the <script> tags..,  so use HTML instead, which will correctly highlight all JavaScript too..

You can also use EOHTML, EOSQL, and EOJAVASCRIPT.
www.feisar.de
28-Apr-2004 02:49
watch out when comparing strings that are numbers. this example:

<?php

$x1
= '111111111111111111';
$x2 = '111111111111111112';

echo (
$x1 == $x2) ? "true\n" : "false\n";

?>

will output "true", although the strings are different. With large integer-strings, it seems that PHP compares only the integer values, not the strings. Even strval() will not work here.

To be on the safe side, use:

$x1 === $x2
atnak at chejz dot com
11-Apr-2004 10:53
Here is a possible gotcha related to oddness involved with accessing strings by character past the end of the string:

$string = 'a';

var_dump($string[2]);  // string(0) ""
var_dump($string[7]);  // string(0) ""
$string[7] === '';  // TRUE

It appears that anything past the end of the string gives an empty string..  However, when E_NOTICE is on, the above examples will throw the message:

Notice:  Uninitialized string offset:  N in FILE on line LINE

This message cannot be specifically masked with @$string[7], as is possible when $string itself is unset.

isset($string[7]);  // FALSE
$string[7] === NULL;  // FALSE

Even though it seems like a not-NULL value of type string, it is still considered unset.
dandrake
19-Jan-2004 11:41
By the way, the example with the "\n" sequence will insert a new line in the html code, while the output will be decided by the HTML syntax. That's why, if you use

<?
 
echo "Hello \n World";
?>

the browser will receive the HTML code on 2 lines
but his output on the page will be shown on one line only.
To diplay on 2 lines simply use:

<?
 
echo "Hello <br>World";
?>

like in HTML.
philip at cornado dot com
12-Apr-2003 12:37
Note that in PHP versions 4.3.0 and 4.3.1, the following provides a bogus E_NOTICE (this is a known bug):

echo "$somearray['bar']";

This is accessing an array inside a string using a quoted key and no {braces}.  Reading the documention shows all the correct ways to do this but the above will output nothing on most systems (most have E_NOTICE off) so users may be confused.  In PHP 4.3.2, the above will again yield a parse error.
03-Mar-2003 06:04
Regarding "String access by character":

Apparently if you edit a specific character in a string, causing the string to be non-continuous, blank spaces will be added in the empty spots.

echo '<pre>';
$str = '0123';
echo "$str\n";
$str[4] = '4';
echo "$str\n";
$str[6] = '6';
echo "$str\n";

This will output:
0123
01234
01234 6
Notice the blank space where 5 should be.
vallo at cs dot helsinki dot fi
04-Nov-2002 01:41
Even if the correct way to handle variables is determined from the context, some things just doesn't work without doing some preparation.

I spent several hours figuring out why I couldn't index a character out of a string after doing some math with it just before. The reason was that PHP thought the string was an integer!

$reference = $base + $userid;
.. looping commands ..
$chartohandle = $reference{$last_char - $i};

Above doesn't work. Reason: last operation with $reference is to store a product of an addition -> integer variable. $reference .=""; (string catenation) had to be added before I got it to work:

$reference = $base + $userid;
$reference .= "";
.. looping commands ..
$chartohandle = $reference{$last_char - $i};

Et voil! Nice stream of single characters.
guidod at gmx dot de
23-Jul-2002 06:26
PHP's double-quoted strings are inherently ill-featured - they will be a problem especially with computed code like in /e-evals with preg_replace.

bash and perl follow the widely accepted rule that all backslashes will escape the nextfollowing char, and nonalpha-chars will always get printed there as themselves whereas (the unescaped chars might have special meaning in regex). Anyway, it is a great way to just escape all nonalpha chars that you uncertain about whether they have special meaning in some places, and ye'll be sure they will get printed literal.

Furthermore, note that \{ sequence is not mentioned in the  escape-char table! You'll get to know about it only "complex (curly) syntax". This can even more be a problem with evals, as they behave rather flaky like it _cannot_ be accomodated for computed code. Try all variants of `echo "hello \{\$world}"` removing one or more of the chars in the \{\$ part - have fun!

数组> <浮点型
Last updated: Sun, 25 Nov 2007
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites