Empty strings seem to be no real strings, because they behave different to strings containing data. Here is an example.
It is possible to change a character at a specific position using the square bracket notation:
<?php
$str = '0';
$str[0] = 'a';
echo $str."\n"; // => 'a'
?>
It is also possible to change a character with does not exist, if the index is "behind" the end of the string:
<?php
$str = '0';
$str[1] = 'a';
echo $str."\n"; // => 0a
?>
But if you do that on an empty string, the string gets silently converted into an array:
<?php
$str = '';
$str[0] = 'a';
echo $str."\n"; // => Array
?>
Strings
Uma string é uma série de caracteres. Antes do PHP 6, um caracter é o mesmo que um byte. Ou seja, há exatamente 256 caracteres diferentes possÃveis. Isto implica que o PHP não tem suporte nativo ao Unicode. Veja utf8_encode() e utf8_decode() para algumas funcionalidades básicas de Unicode.
Nota: Não é problema para uma string ser bastante longa. PHP não impõe limite de tamanho de uma string; o único limite é o de memória disponÃvel do computador no qual o PHP está sendo executado.
Sintaxe
Uma string literal pode ser especificada de quatro formas diferentes.
- apóstrofo
- aspas
- sintaxe heredoc
- sintaxe nowdoc (desde o PHP 5.3.0)
Apóstrofos
A maneira mais simples para especificar uma string é delimitá-la entre apóstrofos (o caracter ').
Para especificar um apóstrofo. você precisará "escapá-la" com uma contra barra (\), como em muitas outras linguagens. Se uma contra barra precisa ocorrer antes de um apóstrofo ou no final da string, você precisa duplicá-la. Note que se você tentar escapar qualquer outro caracter, a contra barra também será impressa! Então geralmente não é necessário escapar a própria contra barra. Para especificar um apóstrofo, use escape (\). Para especificar uma barra invertida antes de uma apóstrofo, ou no final da string, use-o duas vezes (\\). Note que tentando usar escape qualquer outro caractere imprimirá a barra invertida também.
Nota: Diferentemente das duas outras sintaxes, variables e seqüências de escape para caracteres especiais não serão substituÃdas quando elas ocorrerem dentro de strings delimitadas por apóstrofes.
<?php
echo 'isto é uma string comum';
echo 'Você pode incluir novas linhas em strings,
dessa maneira que estará
tudo bem';
// Imprime: Arnold disse uma vez: "I'll be back"
echo 'Arnold disse uma vez: "I\'ll be back"';
// Imprime: Você tem certeza em apagar C:\*.*?
echo 'Você tem certeza em apagar C:\\*.*?';
// Imprime: Você tem certeza em apagar C:\*.*?
echo 'Você tem certeza em apagar C:\*.*?';
// Imprime: Isto não será substituido: \n uma nova linha
echo 'Isto não será substituido: \n uma nova linha';
// Imprime: Variaveis $também não $expandem
echo 'Variaveis $também não $expandem';
?>
Aspas
Se a string é delimitada entre aspas ("), o PHP irá interpretar mais seqüências de escape para caracteres especiais:
| Seqüência | Significado |
|---|---|
| \n | fim de linha (linefeed ou LF ou 0x0A (10) em ASCII) |
| \r | retorno de carro (carriage return ou CR ou 0x0D (13) em ASCII) |
| \t | TAB horizontal (HT ou 0x09 (9) em ASCII) |
| \v | TAB vertical (VT ou 0x0B (11) em ASCII) (desde o PHP 5.2.5) |
| \f | form feed (FF ou 0x0C (12) em ASCII) (desde o PHP 5.2.5) |
| \\ | contra barra ou barra invertida |
| \$ | sinal de cifrão |
| \" | aspas |
| \[0-7]{1,3} | a seqüência de caracteres batendo a expressão regular dos caracteres em notação octal |
| \x[0-9A-Fa-f]{1,2} | a seqüência de caracteres batendo a expressão regular de um caracter em notação hexadecimal |
Como em uma string entre apóstrofos, usar escape em qualquer outro caractere resultará em uma barra invertida sendo mostrada também. Antes do PHP 5.1.1, a barra invertida em \{$var} não era mostrada.
O mais importante recurso de strings delimitadas por aspas está no fato de que nome de variáveis serão substituÃdos. Veja interpretação de strings para detalhes.
Heredoc
Uma terceira maneira para delimitar strings é a sintaxe heredoc: <<<. Após este operador, um identificador é fornecido, e após, um newline. Então vem a própria string, e então o mesmo identificador para fechar a string.
O identificador de fechamento precisa começar na primeira coluna da linha. Além, o identificador precisa seguir as mesmas regras de nomeação que qualquer outro rótulo no PHP: só pode conter caracteres alfanuméricos e sublinhados, e precisa começar com um caracter não numérico ou sublinhado.
É muito importante verificar que a linha do identificador de fechamento não contenha nenhum outro caracter, exceto, possivelmente um ponto e vÃrgula (;). O que significa que o identificador não pode ser indentado, e que não pode haver nenhum espaço ou tabulações antes ou depois do ponto e vÃrgula. É também importante perceber que o primeiro caracter antes do identificador de fechamento precisa ser um caracter de nova linha como esperada por seu sistema operacional. Por exemplo, \n em sistemas UNIX, incluindo Mac OS X. O delimitador de fechamento (possivelmente seguido por um ponto e vÃrgula) precisa também ser seguido por newline.
Se essa regra for quebrada e o identificador de fechamento não estiver perfeito, então ele não será considerado como identificador de fechamento e o PHP irá continuar procurando por um. Se, neste caso, um identificador de fechamento apropriado não for encontrado antes do final do arquivo atual, um erro de interpretação (parse) será lançado na linha final do script.
Heredocs não podem ser usados para inicializar membros de classes. Use ao invés, nowdocs.
Exemplo #1 Exemplo inválido
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
Textos heredoc se comportam como string delimitadas por aspas, com apenas uma diferença. Você não precisa escapar apóstrofos e aspas em seus heredocs, mas você ainda pode continuar utilizando os códigos de escape listados acima. Variáveis são substituÃdas, mas o mesmo cuidado precisa ser tomado quando expressando variáveis complexas dentro de heredocs assim como nas strings.
Exemplo #2 Exemplo de delimitação de strings heredoc
<?php
$str = <<<EOD
Exemplo de uma string
distribuÃda em várias linhas
utilizando a sintaxe heredoc.
EOD;
/* Exemplo mais complexo, com variáveis */
class foo
{
var $foo;
var $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'Meu nome';
echo <<<EOT
Meu nome é "$name". Eu estou imprimindo $foo->foo.
Agora, eu estou imprimindo {$foo->bar[1]}.
Isto deve imprimir um 'A' maiúsculo: \x41
EOT;
?>
O exemplo acima irá imprimir:
My name is "MyName". I am printing some Foo. Now, I am printing some Bar2. This should print a capital 'A': A
É também possÃvel usar sintaxe Heredoc para passar dados para argumento de funções:
Exemplo #3 Exemplo de Heredoc em argumentos
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
Nota: O suporte a heredoc foi acrescentado no PHP 4.
Nowdoc
Nowdocs são para apóstrofos o que heredocs são para aspas dupla em strings. Um nowdoc é especificado similarmente a um heredoc, mas nenhuma análise é feito dentro de um nowdoc. A construção é ideal para colocar códigos PHP ou outros blocos grandes de texto sem a necessidade de usar escapes. Ele compartilha algumas caracterÃsticas em comum com a construção SGML <![CDATA[ ]]>, assim é declarado um bloco de texto onde nada será analisado.
Um nowdoc é identificado com a mesma seqüência <<< usada para heredocs, mas o identificador precisa ficar entre aspas simples, e.g. <<<'EOT'. Todas as regras para identificadores heredoc se aplicam para identificadores nowdoc, especialmente aqueles considerando o identificador de fechamento.
Exemplo #4 Exemplo de string em Nowdoc
<?php
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;
/* Exemplo mais complexo, com variáveis. */
class foo
{
public $foo;
public $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 not print a capital 'A': \x41
EOT;
?>
O exemplo acima irá imprimir:
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41Nota: Diferente de heredocs, nowdocs pode ser usado no contexto de dado estático. O exemplo tÃpico é inicializando membros de classes ou constantes:
Exemplo #5 Exemplo com dado estático
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
Nota: Suporte a Nowdoc foi adicionado no PHP 5.3.0.
Interpretação de variáveis
Quando uma string é especificada dentro de aspas ou heredoc, variáveis são interpretadas dentro delas.
Há dois tipos de sintaxe: um simples e um complexo . A sintaxe simples é a mais comum e conveniente, provendo uma maneira de interpretar uma variável, um valor de array ou uma propriedade de object em uma string com o menor esforço.
A sintaxe completa foi introduzida no PHP 4, e pode ser reconhecida por chaves ({}) envolvendo a expressão.
Sintaxe simples
Se um sinal de cifrão ($) é encontrado, o interpretador tentará obter tantos identificadores quanto possÃveis para formar um nome de variável válido. Envolva o nome da variável com chaves se você deseja explicitamente especificar o fim do nome.
<?php
$cerveja = 'Heineken';
echo "O sabor das '$cerveja's é otimo"; // funciona, "'" é um caracter inválido para nome de variáveis
echo "Ele bebeu algumas $cervejas"; // não funciona, 's' é um caracter válido para nome de variáveis
echo "Ele bebeu algumas ${cerveja}s"; // funciona
echo "Ele bebeu algumas {$cerveja}s"; // funciona
?>
Similarmente, um Ãndice de array ou uma propriedade de object pode ser analisado. Com Ãndices de array, o fechamento de colchete (]) marca o final do Ãndice. A mesma regra aplica-se para propriedade de objetos como para simples variáveis.
<?php
// Esses exemplos são especÃficos para utilização de arrays dentro de strings
// Quando fora de strings, sempre delimite suas chaves de array strings
// e não use {colchetes}.
// Mostra todos os erros
error_reporting(E_ALL);
$fruits = array('morango' => 'vermelho', 'banana' => 'amarelo');
// Funciona, mas note que funciona de maneira diferente fora dos delimitadores de strings
echo "A banana é $fruits[banana].";
// Funciona
echo "A banana é {$fruits['banana']}.";
// Funciona, mas o PHP procura por uma constante chamada 'banana' antes,
// como descrito a abaixo.
echo "A banana é {$fruits[banana]}.";
// Nao funciona, use colchetes. Isto lanca um parse error.
echo "A banana é $fruits['banana'].";
// Funciona
echo "A banana é " . $fruits['banana'] . ".";
// Funciona
echo "Este quadrado tem $square->width metros de lado.";
// Nao funciona. Para uma solução, veja a sintaxe complexa.
echo "Este quadrado tem $square->width00 centÃmetros de lado.";
?>
Para qualquer coisa mais complexa, você precisa utilizar a sintaxe complexa.
Sintaxe complexa (chaves)
Isto não é chamado sintaxe complexa porque a sintaxe em si é complexa, mas porque você pode incluir expressões complexas.
De fato, qualquer valor no namespace pode ser incluido em uma string com esta sintaxe. Simplismente escreva a expressão da mesma forma como apareceria fora da string, e então coloque-o em { e }. Desde que { não pode escapado, esta sintaxe somente mostrará ser reconhecida quando o $ imediatamente seguir o {. Use {\$ para ter um literal {$. Alguns exemplos para fazê-lo claro:
<?php
// Mostra todos os erros
error_reporting(E_ALL);
$bom = 'fantastico';
// Não funciona, imprimindo: Isto é { fantastico}
echo "Isto é { $bom}";
// Funciona, imprimindo: Isto é fantástico
echo "Isto é {$bom}";
echo "Isto é ${bom}";
// Funciona
echo "Este quadrado tem {$square->width}00 centÃmetros de lado.";
// Funciona
echo "Isto funciona: {$arr[4][3]}";
// Isto está errado pela mesma razão que $foo[bar] é errado fora de uma string.
// Em outras palavras, isto ainda funciona MAS porque o PHP primeiro procura pro uma
// constante nomeada foo; um erro do tipo E_NOTICE (undefined constant) será
// disparado.
echo "Isto é errado: {$arr[foo][3]}";
// Funciona. Quanto mexendo com arrays multi dimensionais, sempre use colchetes em volta dos arrays
// quando detro de strings
echo "Isto funciona: {$arr['foo'][3]}";
// Funciona
echo "Isto funciona: " . $arr['foo'][3];
echo "Isto funciona também {$obj->values[3]->name}";
echo "Este é o valor da variável chamada $name: {${$name}}";
echo "Este é o valor da variável usando o valor retornado da getName(): {${getName()}}";
echo "Este é o valor da variável usando o valor retornado da \$object->getName(): {${$object->getName()}}";
?>
Nota: Chamada de funções e métodos dentro de {$} funcionam desde o PHP 5.
Acesso e modificação de caracteres da string
Caracteres nas strings podem ser acessados e modificados apenas especificando o deslocamento baseado em zero do caracter desejado depois da string dentro de colchetes, como um array, $str[42] então pense na string como um array de caracteres.
Nota: Strings podem também ser acessada usando colchetes, como $str{42} para o mesmo propósito. Contudo, esta sintaxe está obsoleto a partir do PHP 6. Use colchetes ao invés.
Escrevendo em um offset fora do intervalo, preenche a string com espaços. Tipos diferentes de inteiro são convertidos para inteiro. Tipo ilegal de offset emite E_NOTICE. Offset negativo emite E_NOTICE na escrita mas na leitura uma string vazia. Somente o primeiro caractere de uma string atribuÃda é usada. Atribuindo uma string vazia designa NUL byte.
Exemplo #6 Alguns exemplos com strings
<?php
// Pega o primeiro caracter da string
$str = 'Isto é um teste.';
$first = $str[0];
// Pega o terceiro caracter da string
$third = $str[2];
// Pega o último caracter da string
$str = 'Isto ainda é um teste.';
$last = $str[strlen($str)-1];
// Modifica o ultimo caracter da string
$str = 'Olhe o mal';
$str[strlen($str)-1] = 'r';
?>
Nota: Acessando variáveis de outros tipos usando [] ou {} silenciosamente retorna NULL.
Funções e operadores úteis
Strings podem ser concatenados utilizando o operador '.' (ponto). Note que o operador '+' (adição) não funciona para isso. Veja operadores de string para mais informações.
Há bastante funções úteis para modificação de strings.
Veja a seção de funções de string para funções gerais e funções de expressões regulares ou a funções para expressão regular compatÃvel com Perl para busca avançada & funcionalidade para substituições.
Há também funções para strings URL e funções para criptografia e descriptografia de strings (mcrypt e mhash).
Finalmente, veja também as funções de tipos de caracteres.
Convertendo para strings
Você pode converter um valor para string utilizando o molde (string), ou a função strval(). Conversão para string é automaticamente realizada no escopo de uma expressão para você onde uma string é necessária. Isto acontece quando você usa as funções echo() ou print(), ou quando você compara o valor de uma variável com uma string. Lendo as seções do manual sobre Tipos e Conversão de Tipos tornará o que se segue um pouco mais claro. Veja também a função settype().
O valor boolean TRUE é convertido para a string "1", o valor FALSE é representado como "" (uma string vazia). Desta forma, você pode converter livremente entre os tipos booleano e string.
Um integer ou um float é convertido para a representação string do número em dÃgitos arábicos (incluindo a parte expoente para um float). Números de ponto flutuante podem ser convertidos usando a notação exponencial (4.1E+6).
Nota: O caractere de ponto decimal é definido no locale do script (categoria LC_NUMERIC). Veja setlocale().
Arrays são sempre convertidos para uma string "Array"; por causa disso echo() e print() não podem por eles mesmo mostrar o conteúdo de um array. Para ver um elemento, use a construção como echo $arr['foo']. Veja abaixo dicas de como exportar/ver todo seu conteúdo.
Objects no PHP 4 são sempre convertidos para a string "Object". Se você quiser imprimir os valores das variáveis membro de um object por razão de debug, leia os parágrafos abaixo. Se você quiser encontrar o nome da classe do qual o objeto é uma instância, use get_class(). No PHP 5, o método __toString é usado se aplicável.
Resources são sempre convertidos para strings na estrutura "Resource id #1" onde 1 é o número único do resource assimilado pelo PHP na execução. Se você quiser obter o tipo do recurso, utilize get_resource_type().
NULL é sempre convertido para uma string vazia.
Como você viu acima, imprimir arrays, objetos ou recursos não fornece qualquer informação útil sobre os seus próprios valores. Veja as funções print_r() e var_dump() para melhores maneiras de imprimir valores para debug.
Você também pode converter valores PHP para strings para armazená-los permanentemente. Este método é chamado serialização, e pode ser feito com a função serialize(). Você também pode serializar valores PHP para estruturas XML , se você ativou o suporte a WDDX na configuração do seu PHP.
Conversão de strings para números
Quando uma string é avaliada como um valor numérico, o valor resultante e o tipo é determinado como segue.
A string será avaliada como um ponto flutuante se conter qualquer um dos caracteres '.', 'e', ou 'E'. Em outros casos, ela será avaliada como um inteiro.
O valor é obtido da porção inicial da string. Se a string começa com dados numéricos válidos, esse será o valor utilizado. Em outro caso, o valor será 0 (zero). Dados numéricos válidos são: um sinal opcional, seguido por um ou mais dÃgitos (opcionalmente contendo um ponto decimal), seguido de um expoente, também opcional. O expoente é um 'e' ou 'E' seguido de um ou mais dÃgitos.
<?php
$foo = 1 + "10.5"; // $foo é float (11.5)
$foo = 1 + "-1.3e3"; // $foo é float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo é integer (1)
$foo = 1 + "bob3"; // $foo é integer (1)
$foo = 1 + "10 Small Pigs"; // $foo é integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo é float (14.2)
$foo = "10.0 pigs " + 1; // $foo é float (11)
$foo = "10.0 pigs " + 1.0; // $foo é float (11)
?>
Para mais informações sobre esta conversão, veja página do manual UNIX de strtod(3).
Para testar qualquer exemplo nesta seção, copie e cole os exemplos e insira a seguinte linha para ver como funciona:
<?php
echo "\$foo==$foo; tipo " . gettype ($foo) . "<br />\n";
?>
Não espere obter o código de um caracter por convertê-lo para inteiro, como é feito em C. Use as funções ord() e chr() para converter entre código de caracteres e os próprios caracteres.
Strings
17-Dec-2009 07:58
20-Oct-2009 07:54
If you want a parsed variable surrounded by curly braces, just double the curly braces:
<?php
$foo = "bar";
echo "{{$foo}}";
?>
will just show {bar}. The { is special only if followed by the $ sign and matches one }. In this case, that applies only to the inner braces. The outer ones are not escaped and pass through directly.
17-Sep-2009 01:08
Although current documentation says 'A string literal can be specified in four different ways: ...', actually there is a fifth way to specify a (binary) string:
<?php $binary = b'This is a binary string'; ?>
The above statement declares a binary string using the 'b' prefix, which is available since PHP 5.2.1. However, it will only have effect as of PHP 6.0.0, as noted on http://www.php.net/manual/en/function.is-binary.php .
03-Sep-2009 05:54
If you need to emulate a nowdoc in PHP < 5.3, try using HTML mode and output capturing. This way '$' or '\n' in your string won't be a problem anymore (but unfortunately, '<?' will be).
<?php
// Start of script
ob_start(); ?>
A text with 'quotes
and $$$dollars$$$.
<?php $input = ob_get_contents(); ob_end_clean();
// Do what you want with $input
echo "<pre>" . $input . "</pre>";
?>
20-Jun-2009 04: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(...)}
?>
21-Mar-2009 06: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
03-Dec-2008 05: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.
16-Nov-2008 02: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.
15-Oct-2008 05: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. ?>
30-Sep-2008 05: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 . '"';
}
?>
11-Sep-2008 12: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)
?>
01-Sep-2008 07: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);
06-Jun-2008 04: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 ;).
30-Apr-2008 04:46
<?php
$F = "F";
function F($s) { return $s; }
$filename = '<some code>';
echo "{$F(htmlspecialchars($filename))}";
?>
31-Mar-2008 11: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
24-Mar-2008 11: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
28-Feb-2008 06: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"
*/
?>
07-Feb-2008 04: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.
28-Jan-2008 02: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.
23-Jan-2008 12: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;
13-Nov-2007 03: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)
?>
05-Nov-2007 10: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...
*/
26-Sep-2007 04: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>";
?>
07-Jul-2007 04: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!
03-Jul-2007 06: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";
01-Jun-2007 12: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"
25-Apr-2007 09: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
24-Apr-2007 02: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;
?>
01-Apr-2007 12: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
27-Feb-2007 05: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';
}
?>
21-Feb-2007 04: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'
28-Mar-2006 05: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.
30-Nov-2005 02: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;
01-Nov-2005 02: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.
27-Oct-2004 04: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.
06-Aug-2004 04: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.
28-Apr-2004 11: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
11-Apr-2004 07: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.
19-Jan-2004 09: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.
11-Apr-2003 09: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.
03-Nov-2002 11: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.
23-Jul-2002 03: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!

Números de ponto flutuante