Práticas recomendadas: trabalhando com seqüências longas e de várias linhas no PHP?

177

Nota: desculpe-me se esta é uma pergunta extremamente simples, mas sou um pouco obsessiva e compulsiva com a formatação do meu código.

Eu tenho uma classe que tem uma função que retorna uma string que compõe o texto do corpo de um email. Quero que este texto seja formatado para que pareça correto no e-mail, mas também para que meu código não pareça estranho. Aqui está o que eu quero dizer:

class Something
{
    public function getEmailText($vars)
    {
        $text = 'Hello ' . $vars->name . ",

The second line starts two lines below.

I also don't want any spaces before the new line, so it's butted up against the left side of the screen.";
        return $text;
    }
}

mas também pode ser escrito como:

public function getEmailText($vars)
{
    $text = "Hello {$vars->name},\n\rThe second line starts two lines below.\n\rI also don't want any spaces before the new line, so it's butted up against the left side of the screen.";
    return $text;
}

mas qual é o problema com novas linhas e devoluções? Qual é a diferença? É \n\no equivalente a \r\rou \n\r? O que devo usar ao criar um espaço entre as linhas?

Depois, há a opção de buffer de saída e sintaxe heredoc.

Como você lida com o uso de longas cadeias de linhas múltiplas em seus objetos?

Andrew
fonte
3
Eu sempre pensei que \ n era nova linha no Unix \ r é nova linha no MacOS antes do OS / X e \ r \ n é nova linha no Windows. Além disso, considerando que essa será uma string que aparece em uma mensagem de email, você deve garantir que, da maneira que estiver fazendo, apareça corretamente na maioria dos clientes de email de comando. Dica: o Outlook remove caracteres extras de nova linha em alguns casos, para que você nem sempre obtenha o que espera.
Kenny Drobnack 04/12/2009
1
Não tenho certeza se isso é tão importante, mas originalmente os dois caracteres 'nova linha' vieram de quando você tinha uma máquina de escrever física que usava dois caracteres. Um para colocar o carro de volta ao lado esquerdo da página (CR - 0xD) e outro que fez com que a página passasse para a próxima linha (LF - 0xA.) Tenho certeza de que existem pessoas que sabem mais sobre isso Contudo.
Mkgrunder 04/12/09

Respostas:

288

Você deve usar HEREDOC ou NOWDOC.

$var = "some text";
$text = <<<EOT
  Place your text between the EOT. It's
  the delimiter that ends the text
  of your multiline string.
  $var
EOT;

A diferença entre o Heredoc e o Nowdoc é que o código PHP incorporado em um heredoc é executado, enquanto o código PHP no Nowdoc será impresso como está.

$var = "foo";
$text = <<<'EOT'
  My $var
EOT;

Nesse caso, $ text terá o valor My $var.

Nota: antes do fechamento, EOT;não deve haver espaços ou tabulações. caso contrário, você receberá um erro

halfdan
fonte
Por quê? Porque tudo entre a primeira EOT e a segunda é considerado uma string como está. O que significa que você não precisa colocar barra invertida n em todas as strings de várias linhas. @Fabian: Qual é a diferença entre um HEREDOC e NOWDOC, ou eles são a mesma coisa?
Kenny Drobnack 04/12/2009
4
@powtac: Não, porque precisa estar em uma nova linha para encerrar um heredoc. Especificamente, ele deve estar EOT;sem espaços antes dele.
Powerlord 04/12/2009
Eu adicionei uma explicação para o Nowdoc.
Halfdan 04/12
6
@halfdan, estou faltando alguma coisa? Por que nos preocupar com heredocs e nowdocs quando podemos simplesmente digitar a tecla "Enter" e cercar a string de várias linhas com aspas, como uma string normal?
Pacerier 05/04
3
Apenas adicione isso à sua resposta: antes da última, EOT;não deve haver espaços ou tabulações. caso contrário, você receberá um erro.
Shnd
44

Eu uso um sistema semelhante ao pix0r e acho que torna o código bastante legível. Às vezes, eu chegava a separar as quebras de linha entre aspas duplas e usava aspas simples para o restante da string. Dessa forma, elas se destacam do restante do texto e as variáveis ​​também se destacam melhor se você usar a concatenação em vez de injetá-las dentro de uma string com aspas duplas. Então, eu poderia fazer algo assim com o seu exemplo original:

$text = 'Hello ' . $vars->name . ','
      . "\r\n\r\n"
      . 'The second line starts two lines below.'
      . "\r\n\r\n"
      . 'I also don\'t want any spaces before the new line,'
      . ' so it\'s butted up against the left side of the screen.';

return $text;

Em relação às quebras de linha, no email você deve sempre usar \ r \ n. PHP_EOL é para arquivos que devem ser usados ​​no mesmo sistema operacional em que o php está sendo executado.

Cvuorinen
fonte
Você definiu esse recuo no seu IDE (para definir uma cadeia de caracteres multilinha alinhada a cada parte)?
Krzysztof Trzos
25

Eu uso modelos para texto longo:

email-template.txt contém

hello {name}!
how are you? 

No PHP eu faço isso:

$email = file_get_contents('email-template.txt');
$email = str_replace('{name},', 'Simon', $email);
Powtac
fonte
interessante ... onde você armazena seus modelos na estrutura de diretórios de um aplicativo da web?
4303 Andrew
Meu código é apenas uma demonstração. Para um aplicativo Web enorme, você pode usar uma estrutura como / templates / emails /, / templates / userfeedback /. Mas se você tiver mais coisas, eu recomendaria um sistema completo de modelos como o SMARTY.
powtac 04/12/2009
O Dwoo dwoo.org é um sistema de templates PHP decente compatível com SMARTY, que alguns consideram um bom sucessor (iniciado no PHP5, portanto, sem bagagem PHP4).
Micahwittman
19

Adicionar \ne / ou \rno meio da string e ter uma linha muito longa de código, como no segundo exemplo, não parece certo: quando você lê o código, não vê o resultado e precisa rolar .

Nesse tipo de situação, eu sempre uso o Heredoc (ou Nowdoc, se estiver usando PHP> = 5.3) : fácil de escrever, fácil de ler, sem necessidade de linhas muito longas, ...

Por exemplo :

$var = 'World';
$str = <<<MARKER
this is a very
long string that
doesn't require
horizontal scrolling, 
and interpolates variables :
Hello, $var!
MARKER;

Apenas uma coisa: o marcador final (e o ' ;' depois dele) deve ser a única coisa na sua linha: sem espaço / tabulação antes ou depois!

Pascal MARTIN
fonte
12

Claro, você poderia usar o HEREDOC, mas, no que diz respeito à legibilidade do código, não é realmente melhor que o primeiro exemplo, envolvendo a cadeia de caracteres em várias linhas.

Se você realmente deseja que sua string de várias linhas tenha uma boa aparência e flua bem com seu código, eu recomendo concatenar as strings juntas da seguinte forma:

$text = "Hello, {$vars->name},\r\n\r\n"
    . "The second line starts two lines below.\r\n"
    . ".. Third line... etc";

Isso pode ser um pouco mais lento que o HEREDOC ou uma sequência de várias linhas, mas fluirá bem com a indentação do seu código e facilitará a leitura.

pix0r
fonte
9

Eu gosto desse método um pouco mais para Javascript, mas parece valer a pena incluir aqui, porque ainda não foi mencionado.

$var = "pizza";

$text = implode(" ", [
  "I love me some",
  "really large",
  $var,
  "pies.",
]);

// "I love me some really large pizza pies."

Para coisas menores, acho que geralmente é mais fácil trabalhar com estruturas de matriz em comparação com seqüências de caracteres concatenadas.

Palavras-chave : implode vs concat performance

johnny
fonte
1

Quem acredita que

"abc\n" . "def\n"

está seqüência de linhas múltiplas está incorreta. São duas cadeias com operador de concatenação, não uma cadeia de linhas múltiplas. Tais seqüências de caracteres concatenadas não podem ser usadas como chaves de matrizes predefinidas, por exemplo. Infelizmente, o php não oferece cadeias multilinhas reais na forma de

"abc\n"
"def\n"

only HEREDOCe NOWDOCsintaxe, que é mais adequado para modelos, porque o recuo do código aninhado é quebrado por essa sintaxe.

Dmitriy Sintsov
fonte
1

você também pode usar:

<?php
ob_start();
echo "some text";
echo "\n";

// you can also use: 
?> 
some text can be also written here, or maybe HTML:
<div>whatever<\div>
<?php
echo "you can basically write whatever you want";
// and then: 
$long_text = ob_get_clean();
Alon Gouldman
fonte
0

Em relação à sua pergunta sobre novas linhas e devoluções:

Eu recomendaria o uso da constante global predefinida PHP_EOL , pois resolverá quaisquer problemas de compatibilidade entre plataformas.

Esta questão foi levantada anteriormente no SO e você pode descobrir mais informações lendo " Quando eu uso a constante PHP PHP_EOL "

Corey Ballou
fonte
1
O comentário a esta resposta sugere que eu deveria usar \ r \ n para novas linhas em e-mails: stackoverflow.com/questions/128560/...
Andrew
0

mas qual é o problema com novas linhas e devoluções? Qual é a diferença? \ N \ n é o equivalente a \ r \ r ou \ n \ r? O que devo usar ao criar um espaço entre as linhas?

Ninguém aqui parecia realmente responder a essa pergunta, então aqui estou eu.

\r representa 'retorno de carro'

\n representa 'feed de linha'

O motivo real deles remonta às máquinas de escrever. À medida que você digitava, o 'carro' deslizava lentamente, caractere por caractere, à direita da máquina de escrever. Quando você chegava ao final da linha, retornava a carruagem e depois passava para uma nova linha . Para ir para a nova linha, você giraria uma alavanca que alimentava as linhas ao redator de texto. Assim, essas ações, combinadas, foram chamadas de avanço de linha de retorno de carro . Tão literalmente:

Um avanço de linha \n, significa mover para a próxima linha.

Um retorno de carro \r, significa mover o cursor para o início da linha.

Por fim, Hello\n\nWorlddeve resultar na seguinte saída na tela:

Hello

     World

Onde como Hello\r\rWorlddeve resultar na seguinte saída .

É somente ao combinar os dois caracteres \r\nque você tem o entendimento comum da linha conhecida. O IE Hello\r\nWorlddeve resultar em:

Hello
World

E, é claro \n\r, resultaria na mesma saída visual que \r\n.

Originalmente, os computadores pegaram \re \nliteralmente. No entanto, atualmente, o suporte para retorno de carro é escasso. Normalmente, em todos os sistemas, você pode usar \nsozinho. Nunca depende do sistema operacional, mas depende do que você está vendo na saída.

Ainda assim, eu sempre aconselho usar \r\nsempre que puder!

Sancarn
fonte