字符串
string 是一系列字符。在 PHP 中,字符和字节一样,也就是说,一共有 256 种不同字符的可能性。这也暗示 PHP 对 Unicode 没有本地支持。请参阅函数 utf8_encode() 和 utf8_decode() 以了解有关 Unicode 支持。
注: 一个字符串变得非常巨大也没有问题,PHP 没有给字符串的大小强加实现范围,所以完全没有理由担心长字符串。
语法
字符串可以用三种字面上的方法定义。
单引号
指定一个简单字符串的最简单的方法是用单引号(字符 ')括起来。
要表示一个单引号,需要用反斜线(/)转义,和很多其它语言一样。如果在单引号之前或字符串结尾需要出现一个反斜线,需要用两个反斜线表示。注意如果你试图转义任何其它字符,反斜线本身也会被显示出来!所以通常不需要转义反斜线本身。
注: 在 PHP 3 中,此情况下将发出一个 E_NOTICE 级的警告。
注: 和其他两种语法不同,单引号字符串中出现的变量和转义序列不会被变量的值替代。
<?php
|
双引号
如果用双引号(")括起字符串,PHP 懂得更多特殊字符的转义序列:
表格 11-1. 转义字符
序列 | 含义 |
---|---|
/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 中其它任何标签的命名规则:只能包含字母数字下划线,而且必须以下划线或非数字字符开始。
警告 |
很重要的一点必须指出,结束标识符所在的行不能包含任何其它字符,可能除了一个分号(;)之外。这尤其意味着该标识符不能被缩进,而且在分号之前和之后都不能有任何空格或制表符。同样重要的是要意识到在结束标识符之前的第一个字符必须是你的操作系统中定义的换行符。例如在 Macintosh 系统中是 /r。 如果破坏了这条规则使得结束标识符不“干净”,则它不会被视为结束标识符,PHP 将继续寻找下去。如果在这种情况下找不到合适的结束标识符,将会导致一个在脚本最后一行出现的语法错误。 |
定界符文本表现的就和双引号字符串一样,只是没有双引号。这意味着在定界符文本中不需要转义引号,不过仍然可以用以上列出来的转义代码。变量会被展开,但当在定界符文本中表达复杂变量时和字符串一样同样也要注意。
注: 定界符支持是 PHP 4 中加入的。
变量解析
当用双引号或者定界符指定字符串时,其中的变量会被解析。
有两种语法,一种简单的和一种复杂的。简单语法最通用和方便,它提供了解析变量,数组值,或者对象属性的方法。
复杂语法是 PHP 4 引进的,可以用花括号括起一个表达式。
简单语法
如果遇到美元符号($),解析器会尽可能多地取得后面的字符以组成一个合法的变量名。如果你想明示指定名字的结束,用花括号把变量名括起来。
<?php
|
同样也可以解析数组索引或者对象属性。对于数组索引,右方括号(])标志着索引的结束。对象属性则和简单变量适用同样的规则,尽管对于对象属性没有像变量那样的小技巧。
<?php
|
对于任何更复杂的情况,应该使用复杂语法。
复杂(花括号)语法
不是因为语法复杂而称其为复杂,而是因为用此方法可以包含复杂的表达式。
事实上,用此语法你可以在字符串中包含任何在名字空间的值。仅仅用和在字符串之外同样的方法写一个表达式,然后用 { 和 } 把它包含进来。因为不能转义“{”,此语法仅在 $ 紧跟在 { 后面时被识别(用“{/$”或者“/{$”来得到一个字面上的“{$”)。用一些例子可以更清晰:
<?php
|
实用函数及操作符
字符串可以用“.”(点)运算符连接。注意这里不能用“+”(加)运算符。更多信息参见字符串运算符。
有很多实用函数来改变字符串。
普通函数见字符串函数库一节,高级搜索和替换见正则表达式函数(两种口味:Perl 和 POSIX 扩展)。
还有 URL 字符串函数,以及加密/解密字符串的函数(mcrypt 和 mhash)。
最后,如果还是找不到你要的函数,参见字符类型函数库。
字符串转换
您可以用 (string) 标记或者 strval() 函数将一个值转换为字符串。当某表达式需要字符串时,字符串的转换会在表达式范围内自动完成。例如当你使用 echo() 或者 print() 函数时,或者将一个变量值与一个字符串进行比较的时候。阅读手册中有关类型和类型戏法中的部分有助于更清楚一些。参见 settype()。
布尔值 TRUE 将被转换为字符串 "1",而值 FALSE 将被表示为 ""(即空字符串)。这样您就可以随意地在布尔值和字符串之间进行比较。
整数或浮点数数值在转换成字符串时,字符串即为表示这些数值数字(浮点数还包含有指数部分)。
数组将被转换成字符串 "Array",因此您无法通过 echo() 或者 print() 函数来输出数组的内容。请参考下文以获取更多提示。
对象将被转换成字符串 "Object"。如果您因为调试需要,需要将对象的成员变量打印出来,请阅读下文。如果您希望得到该对象所依附的类的名称,请使用函数 get_class()。
资源类型将会以 "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
|
此转换的更多信息见 Unix 手册中关于 strtod(3) 的部分。
如果你想测试本节中的任何例子,可以拷贝和粘贴这些例子并且加上下面这一行自己看看会发生什么:
不要指望在将一个字符转换成整型时能够得到该字符的编码(您可能也会在 C 中这么做)。如果您希望在字符编码和字符之间转换,请使用 ord() 和 chr() 函数。
字符串
25-Jan-2005 08:39
It's fun to use heredoc syntax in conjunction with sprintf, and quite effective in my opinion.
sprintf(<<<EOS
The dog ran over the %s,
and landed on the %s
EOS
,'cat','floor');
Dunno if anyone else likes this method, but Its certainly usefull for constructing long verbose SQL statements.
Cheers.
28-Oct-2004 03: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.
10-Sep-2004 06:47
Re: Jonathan Lozinski's note on vim syntax highlighting, we use EOHTML, EOSQL, and EOJAVASCRIPT quite frequently for HTML, SQL, and JavaScript, respectively.
eg:
<?php
$query =<<<EOSQL
SELECT Foo.a,
Foo.b,
Bar.a
FROM Foo
LEFT
JOIN Bar
ON Foo.x=Bar.y
WHERE Foo.b LIKE '%123%'
EOSQL;?>
will be highlighted correctly for SQL under VIM.
07-Aug-2004 03: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.. There might be one for Text/css too?
20-Jul-2004 11:55
The short version for the curly syntax:
1. $str{something} is the equivalent of $str[something]
2. Inside "" strings you can use any variable, no matter how complex the addressing mode (multiple index array, imbricated objects) by enclosing the variable in {}: "foo{$any_variable}bar".
To add to the confusion:
a) The two uses above have nothing in common, conceptually. For instance, #1 can use operations or functions as that something, #2 is restricted to just variables.
b) In #2, you can use either ${ or {$ to open the curly expression ie. "${var}" and "{$var}" are equivalent.
30-Jun-2004 10:59
If you want side effects to occur during variable substituion inside strings, the "?" operator can help. For example:
<?php
$i = 0;
echo <<<LONGSTRING
one {${$i++ ? "i" : "i"}}
two {${$i++ ? "i" : "i"}}
three {${$i++ ? "i" : "i"}}
LONGSTRING;
?>
will print: "one 1 two 2 three 3"
28-Apr-2004 10: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
12-Apr-2004 06: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.
30-Mar-2004 08:04
Make attention to string conversion!
Strings may evaluate to true but also to zero!!
<?
$hello='hi there';
echo($hello?'true':'false'); //true
echo($hello==0?'true':'false'); //true!!!!!
echo($hello===0?'true':'false'); //false
?>
27-Feb-2004 02:46
Remember that even PHP is type less, some convertions like INTEGER to STRING is not done when using character direct access like string functions does.
<?php
$str = '456';
echo strlen($str); // strlen convert int to string automatically
echo $str{0}; // this works
$str = 456;
echo $str{0}; // this NOT works
$str = (string)$str; // do type cast to string
echo $str{1}; // now it works
?>
24-Feb-2004 03:18
If you use the heredoc syntax and you want to insert an function that echo's something use the following escape sequence: {${header('This is text', 'color')}}
This will execute the function.
hope this helps somebody.
G
25-Jan-2004 07:41
If you need to output a string that contains the 'end of php' sequence ?>, or perhaps you have trouble with your editor's syntax colouring because of it, for instance if you wish to do this:
<?php
print "<?xml version=/"1.0/"?>/n";
?>
you can instead use an encoded char to remove the confusion:
<?php
print "<?xml version=/"1.0/"/x3F>/n";
?>
Note that this notes page doesn't have a problem with this syntax!
20-Jan-2004 07: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.
26-Dec-2003 03:00
Re: reuterpl at wp dot pl
No, that's not true.. I mean not exactly true gowever I know what you meant but begginers may not know and feal confused..
<?php
$str = "Hello /n World";
echo($str);
// Output:
// Hello
// World
// Browser renders it as:
// Hello World
echo('<pre>' . $str . '</pre>');
// Output:
// <pre>Hello
// World</pre>
// Browser renders it as:
// Hello
// World
$str = nl2br($str);
echo($str);
// Output:
// Hello <br /> World
// Browser renders it as:
// Hello
// World
echo('<pre>' . $str . '</pre>');
// Output:
// <pre>Hello <br /> World</pre>
// Browser renders it as:
// Hello
//
// World
?>
Re: cs_1 at gmx dot de
I use only UNIX line ends an have no problems with heredoc syntax, so maybe your problem was with something else..
29-Aug-2003 03:42
In response to the most recent post, by Edwin: Huh?
First, $foo is not NULL terminated, it's newline terminated. NULL and /n are not even remotely the same thing.
Second, the example you posted works perfectly. Both values get computed and printed as 3.0, not 2.0.
06-Jun-2003 05:58
This one took me a while to sort out:
$foo = "1.5/n";
$bar = "1.5";
printf ("%6.2f, %6.2f ", $foo*2, $bar*2);
>> 2.0, 3.0
So apparently string conversion is messed up by NULL, an obvious solution in case you happen to have a NULL terminated string is:
$foo = rtrim ($foo);
25-Apr-2003 02:57
This is how I did it, if tou need to cut big text blocks in easy to browse text blocks:
$str = "bla bla nla. asdfasd. fdsfd fafsasf. asasdwe fdscz asdvc. afasffas. afafs vcxrqw cvea.";
preg_match_all("/.{1500,}?/./s",$str,$out,PREG_PATTERN_ORDER);
list($out) = $out;
print_r($out);
And this is the dynamic menu to navigate between the blocks:
for ($i=0; $i<count($out); $i++) {
$pgnum = $i+1;
echo "<option value=$pgnum>$pgnum</option>";
}
12-Apr-2003 08: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.
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.
(PHP 4.3.1)
12-Feb-2003 04:57
Be sure to save your PHP files with CrLf line ends when using the heredoc syntax for a variable, e.g.:
$var1 = <<<EOT
sdsdsd
EOT;
didn't work on my linux system when using unix line ends...
25-Jan-2003 03:28
This is why this is right:
$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
In all these examples, the php code is looking for the variable $beer.
In the first one, it works because when it finds $beer's it actually finds $beer and stops at the '.
In the second one, it doesn't work because there is no variable designated as $beers.
The third one works because the php code reads { and } as specifying what the actually variable is that it should be looking for. The { and } allow you to add onto the variable.
18-Jan-2003 11:09
ERRATA?
Shouldn't this :
echo "$beer's taste is great"; // works, "'" is an invalid character for varnames
echo "He drank some $beers"; // , 's' is a valid character for varnames
echo "He drank some ${beer}s"; // works
be like that:
echo "$beer's taste is great"; // won't work, "'" is an invalid character for varnames
echo "He drank some $beers"; // works, 's' is a valid character for varnames
echo "He drank some ${beer}s"; // works
04-Nov-2002 09: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.
16-Aug-2002 10:08
If you need to escape "$" to be escaped in the output, you need "$" - or maybe even more!
$ is a control character in Latex. If you want it to become /$ for further processing through Latex, it seems that there must be 4 (!) backslashes - so that in the end there is one left after processing the string twice. Once through str_replace and once through preg_replace!
Using 4.1.0 on Windows.
23-Jul-2002 02: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!
//Some more useful examples (and some that are only interesting):
$foo = 1 + "010";
//$foo is 11, not 9 - i.e. PHP doesn't recognize 010 as octal.
$foo = 1 + "0x10";
//$foo is 17 - i.e. PHP DOES recognize 0x10 as hex for 16.
$foo = 1 + "/x10";
$bar = 1 + "/x35"; //0x35 is ASCII for '5'
//$foo is 1, but $bar is 6.
$foo = 1 + "0x/x41/x31"; //0x41 is ASCII 'A'; 0x31 is '1'
//$foo is 162: 1 + 0xA1 = 1 + 161.
/*NOTE: These examples were "discovered" using PHP4, Apache2,
Red Hat 7.2*/
17-Aug-2001 09:07
see 'String conversion':
'...Otherwise, the value will be 0 (zero).'
now look at this:
<?php if (0=='yes') echo "no!!!"; ?>
yes, it really says "no!!!"
...just something to keep in mind...
11-Aug-2000 04:38
A nice "Introduction to PHP Strings" tutorial:
http://www.zend.com/zend/tut/using-strings.php
02-Feb-2000 07:28
The new line is very similar to VBScript's "vbcrlf". The only place where you will see the new line is in the "Post-Parsed" Code. The '/n' can also be used to format Email's and Text Files that PHP is writting.
So in closing, use '<br>' to create a new line for your HTML Page and use '/n' to format the Code and Text Files