Recursos ocultos do PHP? [fechadas]

174

Eu sei que isso soa como uma pergunta de merda, mas deixe-me explicar de onde venho.

Fora da faculdade, consegui um emprego em uma loja de PHP. Eu trabalhei lá por um ano e meio e pensei que tinha aprendido tudo o que havia para aprender sobre programação.

Então, consegui um emprego como uma loja de desenvolvimento interno individual em uma empresa considerável, onde todo o trabalho era em C #. No meu compromisso com a posição, comecei a ler uma tonelada de blogs e livros e rapidamente percebi o quanto eu estava errada ao pensar que sabia tudo. Aprendi sobre testes de unidade, injeção de dependência e padrões de decorador, o princípio de design de acoplamentos soltos, a composição sobre o debate sobre herança e assim por diante - e continuo absorvendo tudo isso. Escusado será dizer que meu estilo de programação mudou completamente no ano passado.

Agora eu me pego pegando um projeto php fazendo alguma codificação para a inicialização de um amigo e me sinto completamente constrangido em oposição à programação em C #. Realmente me incomoda que todas as variáveis ​​em um escopo de classe devam ser referidas anexando '$ this->'. Me incomoda que nenhum dos IDEs que eu tentei tenha muito bom senso e que meus métodos de teste de unidade SimpleTest tenham que começar com a palavra 'test'. Isso me deixa louco porque a digitação dinâmica me impede de especificar implicitamente qual tipo de parâmetro um método espera, e que você precisa escrever uma instrução switch para sobrecarregar o método. Não suporto que você não possa ter namespaces aninhados e precise usar o operador :: para chamar o construtor da classe base.

Agora, não tenho intenção de iniciar um debate entre PHP e C #, mas o que quero dizer é que tenho certeza de que existem alguns recursos do PHP que eu não conheço ou que ainda não consigo usar corretamente. Estou no meu universo C # e estou tendo problemas para enxergar fora da tigela de vidro.

Então, eu estou perguntando, quais são seus recursos favoritos do PHP? Quais são as coisas que você pode fazer e não pode ou é mais difícil nos idiomas .Net?

George Mauer
fonte
Paradigma OO quebrado? Para mim, é o pior recurso "oculto" que você descobre.
knoopx
Esses tópicos são meio engraçados ... Porque para a equipe que trabalho com "recurso oculto" é uma frase de código que significa "bug". E você sabe o que ... Às vezes, descobrir uma característica escondida não é necessariamente uma coisa boa ...
Ganesh Shankar
@Ganesh bug de um homem é outra característica escondida mans ...
Xeoncross

Respostas:

328

Documentação . A documentação recebe meu voto. Não encontrei uma documentação on-line mais completa para uma linguagem de programação - tudo o que tenho para reunir em vários sites e páginas de manual.

Kyle Cronin
fonte
60
Concordo. Ser capaz de digitar www.php.net/function_name e obter uma referência na maioria das vezes é ótimo.
Allain Lalonde
1
Este é um ótimo recurso do PHP, mas eu realmente não o chamaria de oculto ... Se você já pesquisou por parâmetros de método, etc, acabaria no php.net.
John Bubriski
27
Eu também concordo. A melhor coisa do manual são os comentários do usuário. Eu raramente vi outras documentações terem essas. Eles podem conter gemas reais. A única desvantagem é que IMHO eles podados um pouco cedo demais.
21119 Sander Marechal
3
@Phoexo "um pouco menos legível" ??? Eu nunca entendi e nunca vou entender o MSDN, enquanto os documentos PHP são fáceis e claros.
22610 lauriys
3
Discordo. A única razão pela qual a documentação é "boa" é por causa de alguns dos comentários do usuário preencherem todos os buracos nas notas oficiais.
Rob Howard
179

Matrizes . A julgar pelas respostas a esta pergunta, acho que as pessoas não apreciam completamente o quão fácil e útil são as matrizes em PHP. Matrizes PHP agem como listas, mapas, pilhas e estruturas de dados genéricas, tudo ao mesmo tempo. As matrizes são implementadas no núcleo do idioma e são usadas em todo o lugar, o que resulta em boa localidade do cache da CPU. O Perl e o Python usam construções de linguagem separadas para listas e mapas, resultando em mais cópias e transformações potencialmente confusas.

user8134
fonte
11
Os elementos da matriz PHP são ordenados.
user8134
117
Minha mudança inicial do PHP para o C # quase me matou. Em C #, matrizes são apenas uma estrutura simples com tamanho estático e índice numérico. Em PHP, matrizes são a fita adesiva do universo!
Dinah
4
Eu também concordo. Ao jogar com Java para uma tarefa da Uni, fiquei surpreso com o quão rígidos eles eram, sem flexibilidade alguma. Realmente me fez apreciar como as matrizes PHP são boas.
Christian
11
Tenho certeza que matrizes php são ótimas, mas 40 votos no comentário que bate em matrizes C #? Se uma matriz C # não atender à necessidade, há muitas opções. ArrayList e coleções genéricas são muito poderosas. Existem vários tipos de coleções para necessidades específicas. A única vantagem real do php a esse respeito é que ele não fornece nenhuma opção da qual um programador deve decidir. Você usa matriz ou não possui uma variável indexável.
G-Wiz
24
Por outro lado, a sintaxe para matrizes é uma porcaria completamente. Em muitas linguagens de script, você pode criar uma matriz 2D simples assim: [[1, 2], [3, 4]], comparar isso com a versão PHP: array(array(1, 2), array(3, 4)).
Rene Saarsoo
167

Os manipuladores de fluxo permitem que você estenda o "Sistema de arquivos" com uma lógica que, até onde eu sei, é bastante difícil de fazer na maioria dos outros idiomas.

Por exemplo, com o manipulador de fluxo do MS-Excel, você pode criar um arquivo do MS Excel da seguinte maneira:

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) { 
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50),  
    array("Name" => "Popo Jijo", "Age" => 75),  
    array("Name" => "Tiny Tim", "Age" => 90)
); 

fwrite($fp, serialize($data));
fclose($fp);
Allain Lalonde
fonte
Acredito que a estrutura do KIO permita que você faça isso também, mas isso está disponível apenas para aplicativos de desktop baseados no KDE.
MiffTheFox 6/06/09
21
IMHO ter uma abordagem OO adequada seria muito mais sensível do que essa bagunça com os manipuladores de fluxo. Sim, é engraçado poder ler / gravar arquivos do Excel, mas precisa funcionar assim?
Anti Veeranna 22/08/2009
3
Talvez sim, mas essa abordagem resume a complexidade em uma interface comum à maioria dos desenvolvedores de PHP ... sem exigir que eles aprendam conceitos orientados a objetos que possam estar além deles.
Allain Lalonde
13
Se você estiver trabalhando com o Amazon S3, confira o Zend_Amazon_S3, que fornece uma interface de fluxo para URLs como 's3: // {bucket-name} / path'.
davidtbernal 13/09/09
Eu usei isso para criar uma DSL simples para a minha camada de visualização, apenas lendo o arquivo PHP, fazendo alguma substituição de string e passando através de eval (). Por exemplo, eu fiz isso de maneira que eu possa usar tags curtas sempre que escolher e executar @ -> someVar para que eu possa acessar dados no nível da visualização.
Jasper Bekkers
131

Métodos mágicos são métodos de passagem que são chamados sempre que você invoca um método que não existe, atribui ou lê uma propriedade que não existe, entre outras coisas.

interface AllMagicMethods {
    // accessing undefined or invisible (e.g. private) properties
    public function __get($fieldName);
    public function __set($fieldName, $value);
    public function __isset($fieldName);
    public function __unset($fieldName);

    // calling undefined or invisible (e.g. private) methods
    public function __call($funcName, $args);
    public static function __callStatic($funcName, $args); // as of PHP 5.3

    // on serialize() / unserialize()
    public function __sleep();
    public function __wakeup();

    // conversion to string (e.g. with (string) $obj, echo $obj, strlen($obj), ...)
    public function __toString();

    // calling the object like a function (e.g. $obj($arg, $arg2))
    public function __invoke($arguments, $...);

    // called on var_export()
    public static function __set_state($array);
}

Um desenvolvedor de C ++ aqui pode notar que o PHP permite sobrecarregar alguns operadores, por exemplo, ()ou (string). Na verdade, o PHP permite sobrecarregar ainda mais, por exemplo, o []operador ( ArrayAccess ), a foreachconstrução da linguagem ( Iterator e IteratorAggregate ) e a countfunção ( Countable ).

NikiC
fonte
4
Como exemplo útil do que pode ser alcançado com métodos mágicos, vá para phpcodetips.blogspot.com/2008/07/domain-model-validation.html
grom
6
Discordo. Isto é muito mais fraco do que instalações semelhantes em Smalltalk, Ruby & Python (e presumivelmente ele foi copiado de um destes)
finnw
34
O fato de a implementação dessa funcionalidade pelo PHP ser mais fraca que as outras linguagens não a torna menos útil no PHP.
Allain Lalonde
2
__call()é grande em estruturas com mapa domain.com/controller/method/
alex
7
Os métodos mágicos também são lentos como o inferno. Use-os com cuidado.
21720 Alex Weinstein
95

A classe padrão é um contêiner limpo. Eu só aprendi sobre isso recentemente.

Em vez de usar uma matriz para armazenar atributos do servidor

$person = array();
$person['name'] = 'bob';
$person['age'] = 5;

Você pode usar uma classe padrão

$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

Isso é particularmente útil ao acessar essas variáveis ​​em uma string

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";
Dean Rather
fonte
43
"{$ person ['name']} tem {$ person ['age']} anos" funciona.
Kornel
27
"pessoa [nome] tem $ pessoa [idade] anos" também funcionará ... Sem aspas, sem chavetas :) #
majelbstoat 24/11/2008
16
$ string = sprintf ("% s tem% d anos.", $ person ['name'], $ person ['age']);
Daniel Sloof 10/05/09
60
Enquanto nós estamos sobre o assunto: (objeto) array ( "nome" => 'bob', 'idade' => 5)
Annika Backstrom
30
@majelbstoat: Tirar as aspas atrasaria o script, porque o intérprete PHP procurará ver se 'nome' e 'idade' foram definidos com define (...). Também é uma prática ruim, considerando que seria possível inverter totalmente as teclas acessadas em cada caso: define ('idade', 'nome'); define ('nome', 'idade');
brianreavis
90

Os arquivos de inclusão podem ter um valor de retorno que você pode atribuir a uma variável.

// config.php
return array(
    'db' => array(
        'host' => 'example.org',
        'user' => 'usr',
        // ...
    ),
    // ...
);

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org
Philippe Gerber
fonte
@ Peter MUITO útil para o tratamento de erros de exceção db-> localhost.
Talvi Watia
É conveniente para configurar um arquivo de configuração rápido e sujo.
Frank Farmer
Por que você retorna essa matriz? Se um arquivo incluído contiver uma matriz, ele poderá ser usado na inclusão imediatamente.
precisa saber é
5
@fabrik porque seria variável global e disponível em todo o escopo principal. Isso é bastante desagradável, é muito melhor.
Mikulas Dite
Eu trabalhei em um projeto no framework Yii e esse projeto tem um arquivo de configuração em que a matriz foi retornada assim, agora eu entendo por que o arquivo era assim.
Simer Twilio Toronto developer
83

Você pode tirar vantagem do fato de o oroperador ter precedência menor do =que fazer isso:

$page = (int) @$_GET['page'] 
  or $page = 1;

Se o valor da primeira atribuição for avaliado true, a segunda atribuição será ignorada. Outro exemplo:

$record = get_record($id) 
  or throw new Exception("...");
rotações
fonte
7
Não estou convencido disso, acho; mesmo que pareça não ser propenso a erros, é contra-intuitivo e, por si só, pode promover erros.
thomasrutter
14
@ Tortas: uma maneira é a seguinte, código bastante confuso para ser honesto: $ page = isset ($ _ GET ['page'])? (int) $ _ GET ['página']: 1; // A vantagem disso é que não é necessária a supressão de erros.
DisgruntledGoat
3
pensando melhor, já que você está procurando um número inteiro, você pode usar: $ page = is_int ($ _ GET ['page'])? $ _GET ['página']: 1;
DisgruntledGoat
4
É importante notar que o código depois orserá executado se o código anterior orresultar no valor numérico 0. Portanto, semanticamente, pode ser menos provável com algo assim $_GET['page'], mas obviamente a circunstância pode surgir e é bom prestar atenção.
Eyelidlessness
3
Também é importante notar que o oroperador é uma versão com precedentes mais baixos do ||operador. Além disso, +1 porque é altamente expressivo e muitas vezes esqueço que é possível. Deve ser usado com mais frequência e é absolutamente claro o que faz. Eu não sei como código "homens de verdade", então não posso comentar sobre isso.
Eyelidlessness
80

__autoload()arquivos (de classe) auxiliados por set_include_path().

Agora, no PHP5, é desnecessário especificar longas listas de instruções "include_once" ao fazer OOP decente.

Basta definir um pequeno conjunto de diretórios no qual os arquivos da biblioteca de classes são estruturados de maneira adequada e defina o caminho de inclusão automática:

set_include_path(get_include_path() . PATH_SEPARATOR . '../libs/');`

Agora a __autoload()rotina:

function __autoload($classname) {
    // every class is stored in a file "libs/classname.class.php"

    // note: temporary alter error_reporting to prevent WARNINGS
    // Do not suppress errors with a @ - syntax errors will fail silently!

    include_once($classname . '.class.php');
}

Agora, o PHP incluirá automaticamente os arquivos necessários sob demanda, economizando tempo e memória de análise.

Wimmer
fonte
é melhor usar o spl_autoload_register ()?
Alex
19
Claro! __autoload () é PHP4, mas spl_autoload_register () é um "encadeamento" não destrutivo de métodos de carregamento automático.
Willem
3
Um recurso útil, mas a única ressalva é quando você encontra uma instância de uma determinada classe, e fica um pouco mais difícil procurar o local de um arquivo de classe. A definição explícita de inclusões na parte superior fornece uma lista finita de classes envolvidas e sua localização exata.
Cory Casa
É um recurso interessante, mas apenas para contornar a situação de não ter código pré-compilado, para que não saiba onde a classe estará. A grande desvantagem disso é que você não pode ter 2 classes com o mesmo nome, mesmo que elas estejam em espaços para nome diferentes.
Kibbee
3
Consulte o artigo PSR-0 do PHP Standards Working Group (com desenvolvedores de ZF, Symfony, Doctrine, CakePHP, Solar etc.) ao implementar o carregamento automático: groups.google.com/group/php-standards/web / psr-0-proposta-final
Philippe Gerber
76

Facilidade . O maior recurso é como é fácil para os novos desenvolvedores sentar e escrever scripts "trabalhando" e entender o código.

O pior recurso é como é fácil para os novos desenvolvedores sentar e escrever scripts "trabalhando" e achar que eles entendem o código.

A abertura da comunidade em torno do PHP e a enorme quantidade de projetos PHP disponíveis como código aberto são muito menos intimidantes para quem entra no mundo do desenvolvimento e, como você, pode ser um trampolim para linguagens mais maduras.

Não discutirei as coisas técnicas que muitos antes de mim têm, mas se você considerar o PHP como uma comunidade e não como uma linguagem da web, uma comunidade que claramente o abraçou quando você começou a desenvolver, os benefícios realmente falam por si.

Chris Ridenour
fonte
3
Definitivamente um bom comentário. Python foi minha primeira linguagem e foi incrível, mas a falta de projetos que eu me sentia capaz de entender criou uma barreira. Com o PHP, posso procurar praticamente qualquer coisa na documentação e descobrir ... os recursos disponíveis na Web são incríveis.
dscher
76

Variáveis ​​e funções variáveis, sem dúvida!

$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!

O mesmo conceito se aplica aos parâmetros do objeto ($ some_object -> $ some_variable);

Muito muito bom. Crie códigos com loops e padrões muito fáceis, e é mais rápido e mais controlado do que o eval (Thanx @Ross & @Joshi Spawnbrood!). T

Jrgns
fonte
111
variáveis ​​variáveis ​​estão realmente tornando o código menos legível e mais propenso a erros.
Elzo Valugi 09/07/2009
8
E as pessoas realmente usam isso? Cara, eu odiaria ler essas fontes.
Gary Willoughby
27
Variáveis ​​variáveis ​​são um dos piores recursos que o PHP oferece.
davidtbernal 13/09/09
10
9 Em 10 vezes, as variáveis ​​variáveis ​​são melhor substituídas por matrizes, para que você tenha todos os dados em um único local, é possível iterar sobre eles, etc. Somente em algumas circunstâncias muito específicas elas podem ser úteis.
Jasper Bekkers
7
Por favor, não faça novatos usarem esse "recurso".
Uísque
68

Você pode usar funções com um número indefinido de argumentos usando o func_get_args().

<?php

function test() {

    $args = func_get_args();
    echo $args[2]; // will print 'd'
    echo $args[1]; // will print 3
}

test(1,3,'d',4);

?>
TheBrain
fonte
1
Estava prestes a postar isso. Como a propriedade de argumentos nas funções JS.
alex
67

Eu amo arquivos remotos . Para o desenvolvimento da web, esse tipo de recurso é excepcionalmente útil.

Precisa trabalhar com o conteúdo de uma página da web? Um simples

$fp = fopen('http://example.com');

e você já tem um identificador de arquivo pronto, como qualquer outro arquivo normal.

Ou que tal ler um arquivo ou página da Web remota diretamente em uma string?

$str = file_get_contents('http://example.com/file');

A utilidade desse método em particular é difícil de exagerar.

Deseja analisar uma imagem remota? Que tal fazê-lo via FTP?

$imageInfo = getimagesize('ftp://user:[email protected]/image/name.jpg');

Quase todas as funções PHP que funcionam com arquivos podem funcionar com um arquivo remoto. Você pode igualar include()ou require()codificar arquivos remotamente dessa maneira.

zombat
fonte
2
Isso é tão legal! Para fazer isso, por exemplo, em Java, você precisa incluir um zilhão de arquivos jar e escrever um monte de código padrão.
22610 Kimble
16
"Você pode até incluir () ou exigir () arquivos de código remotamente dessa maneira." É claro que incluir () um arquivo em um servidor que você não controla é uma péssima idéia.
Frank Farmer
4
@Frank - sim, bem, seria de presumir que você estaria incluindo o código a partir de um servidor que fez controle.
zombat
1
A questão é que a inclusão remota de arquivos é um problema de segurança comum do PHP: en.wikipedia.org/wiki/Remote_File_Inclusion#PHP .
Frank Farmer
63

strtr ()

É extremamente rápido, tanto que você ficaria surpreso. Internamente, provavelmente usa alguma estrutura maluca do tipo b-tree para organizar suas correspondências pelos prefixos comuns. Eu o uso com mais de 200 localizações e substituições de strings e ele ainda passa por 1 MB em menos de 100ms. Apesar de todas as seqüências trivialmente pequenas, strtr () é significativamente mais rápido que strtolower () ao fazer exatamente a mesma coisa, mesmo levando em consideração o conjunto de caracteres. Você provavelmente poderia escrever um analisador inteiro usando chamadas strtr sucessivas e seria mais rápido que a correspondência de expressão regular usual, descobrir o tipo de token, produzir isso ou aquilo, o próximo tipo de expressão regular.

Eu estava escrevendo um normalizador de texto para dividir o texto em palavras, com letras minúsculas, remover pontuação etc.

thomasrutter
fonte
1
Provavelmente é mais rápido porque substitui caracteres únicos.
Staticsan
10
strtr () não faz apenas substituições de caracteres únicos. Ele pode substituir substrings de comprimento arbitrário por outros substrings de comprimento arbitrário, e ainda parece muito rápido.
thomasrutter
1
Você mencionou que era mais rápido que o strtolower em alguns casos, você pode provar? Fiz um pequeno benchmark e achei falso.
The Pixel Developer
1
Descobri que em pequenas seqüências de digamos 80 caracteres era mais lento que em strtolower, e em grandes sequências de digamos 1 MB era mais rápido. Provavelmente existe algum tipo de custo fixo adicional toda vez que é chamado. Eu estava simplesmente usando strtr ($ this-> string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); A corda em que eu estava operando era um texto típico em inglês ("A raposa marrom rápida", esse tipo de coisa).
thomasrutter
Acabei de ler este post e, em seguida, fiz algumas pesquisas no Google e encontrei: simplemachines.org/community/index.php?topic=175031.0 Alguma idéia de qual é o certo?
Flipper
61

Um recurso não tão conhecido do PHP é extract()uma função que descompacta uma matriz associativa no espaço de nomes local. Provavelmente isso existe para o aborto autoglobal, mas é muito útil para modelar:

function render_template($template_name, $context, $as_string=false)
{
    extract($context);
    if ($as_string)
        ob_start();
    include TEMPLATE_DIR . '/' . $template_name;
    if ($as_string)
        return ob_get_clean();
}

Agora você pode usar render_template('index.html', array('foo' => 'bar'))e somente $foocom o valor "bar"aparece no modelo.

Armin Ronacher
fonte
15
Eu ia ficar com raiva de você por sugerir extract () de qualquer forma, era uma boa característica. Mas acho que esse uso é bastante útil. Suponho que é a única vez que o vi usado, onde é uma boa ideia!
thomasrutter
5
extract () simplifica bastante a execução do seu próprio sistema de modelagem extremamente leve. +1
Dinah
14
Seu inverso, compacto (), também é bom: $ a = 1; $ b = 2; compacto ('a', 'b'); // == array ('a' => $ a, 'b' => $ b)
Annika Backstrom
2
Sim, esse é provavelmente o único uso realmente bom de extract ().
staticsan
4
Eu sugeriria não usar palavras comuns como nomes de argumentos de função nesse caso, pois o contexto $ do qual você extrai () pode conter valores nos índices 'as_string' ou 'template_name'. Usando EXTR_SKIP é aceitável, mas só se move o problema em outro lugar (ou seja, se o modelo está esperando um $ as_string ele vai ficar o valor incorreto para ele.)
Michał Tatarynowicz
52

Range () não está oculto por si só, mas ainda vejo muitas pessoas interagindo com:

for ($i=0; $i < $x; $i++) { 
    // code...
}

quando eles poderiam estar usando:

foreach (range(0, 12) as $number) {
    // ...
}

E você pode fazer coisas simples como

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}
Darren Newton
fonte
3
você pode executar foreach ($ array como $ key => $ value) {}, o que é ainda mais simples.
23410 SilentGhost
15
Pode ser uma micro-otimização, mas vale a pena notar que, por enquanto, são muito mais rápidos e consomem menos memória que o foreach.
217 JAL
3
Você deve tentar o Python. É tão simples quanto "for i in range (12)", ou você pode usar o xrange mais eficiente.
Ponkadoodle
2
@ SilentGhost: você ainda precisa de uma matriz para começar, o que nem sempre é o caso. @ Newbie: elaborado por favor?
Alec
1
@ flexxy, separadamente, não é. Considere o seguinte: phpbench.com role para baixo até Read Loop.
camarada
44

O espaço na web habilitado para PHP geralmente é mais barato do que algo com (asp) .net. Você pode chamar isso de recurso ;-)

VolkerK
fonte
3
Também é muito mais barato configurar vários servidores, se você não precisar pagar pelo Windows Server em cada um.
MiffTheFox 6/06/09
4
O único lugar que eu sei onde o Windows é econômico é em uma universidade que obtém descontos STEEEEP no software para servidores, na medida em que é mais barato para meu departamento comprar 100 cópias do Windows do que treinar nossos administradores no Linux (que parcialmente me deixa triste, mas a configuração do Windows é limpa e bem configurada).
21410 dcousineau
4
Por agora, mas você tem que fazer a troca apenas uma vez, enquanto você vai ter que comprar novas licenças mais cedo ou mais tarde ...
e-satis
42

A staticpalavra-chave é útil fora do ponto de vista do OOP. É possível implementar rápida e facilmente 'memorização' ou cache de funções com algo tão simples como:

<?php
function foo($arg1)
{
    static $cache;

    if( !isset($cache[md5($arg1)]) )
    {
        // Do the work here
        $cache[md5($arg1)] = $results;
    }

    return $cache[md5($arg1)];
}
?>

A staticpalavra-chave cria uma variável que persiste apenas dentro do escopo dessa função após a execução. Essa técnica é ótima para funções que atingem o banco de dados como get_all_books_by_id(...)ou get_all_categories(...)que você chamaria mais de uma vez durante o carregamento da página.

Advertência: Certifique-se de encontrar a melhor maneira de criar uma chave para o seu hash, em quase todas as circunstâncias md5(...)acima não é uma boa decisão (problemas de velocidade e comprimento de saída), usei-a para fins ilustrativos. sprintf('%u', crc32(...))ou spl_object_hash(...)pode ser muito melhor dependendo do contexto.

dcousineau
fonte
7
Apenas um recurso copiado do C / C ++
GetFree
2
@ GetFree Eu não acho que alguém negaria que quase todo o PHP foi copiado de C, C ++, Perl, etc. #
Frank Farmer
1
Copiar é a melhor coisa que pode ser feita.
NikiC 30/08/10
1
PHP ruim. Está sempre copiando recursos de outras pessoas. Deve escrever tudo do zero! (No caso da menor possibilidade de este ser levado a sério: Eu estou brincando)
Halil Özgür
42

Um recurso interessante do PHP é a CLI . Não é tão "promovido" na documentação, mas se você precisar de scripts de rotina / aplicativos de console, o uso do cron + php cli é muito rápido de desenvolver!

Lucacri
fonte
Eu realmente deveria olhar para isso, tenho vários trabalhos cron que buscam um script PHP através de #wget http://example.com...
DisgruntledGoat
A CLI também é uma excelente maneira de detectar erros, pois avisos / erros serão exibidos sem que você precise alterar suas preferências de relatório de erros.
Glacials
40

Então, "e imprima" o truque

<?php $flag and print "Blah" ?>

Ecoará Blah se $ flag for verdadeiro. NÃO FUNCIONA COM ECO.

Isso é muito útil no modelo e substitui o? : que não são realmente fáceis de ler.

e-satis
fonte
24
Eu mesmo acho o operador ternário muito mais óbvio do que explorar o curto-circuito de avaliação de um lógico e.
Vicent Marti
26
Na verdade, esse é o mesmo número de caracteres que <? Php if ($ flag) imprime "Blah"
muito php
3
Parênteses não são tão fáceis de escrever como "e", especialmente no meu teclado francês sangrenta ;-)
e-satis
7
@ todos os comentários - Não se trata de quão curto você pode obtê-lo! Trata-se de legibilidade e facilidade de uso para pessoas-modelo, que às vezes nem são programadores.
Tor Valamo
6
Gostaria de comentar que a declaração if () é mais fácil e mais legível. É certamente mais fácil para mim entender do que explorar essencialmente um efeito colateral do operador 'and' no PHP, onde é fácil cometer um erro (ou parecer que é um erro quando você lê o código mais tarde). Por exemplo, como declarado, isso não funcionará da maneira que você deseja com 'eco'. Com if () não há truques como este.
thomasrutter
37

Você pode usar caracteres negativos em nomes de variáveis como este:

class style
{
  ....
  function set_bg_colour($c)
  {
    $this->{'background-color'} = $c;
  }
}

Por que usar isso? Não faço ideia: talvez para um modelo CSS? Ou algum JSON estranho que você precisa produzir. É uma característica estranha :)

monk-e-boy
fonte
2
Isso funciona com nomes de métodos? Poderia ser útil para os quadros que usam um roteador e quero domain.com/something-with-minuses/view/
alex
6
Os chavetas permitem acessar as propriedades do objeto que têm hífens, pontos e outras entidades não alfanuméricas. Uma razão para usá-lo é ao lidar com xml, onde os nomes das entidades podem ser pontilhados como em NITF / NewsML <body.content>. Se você usa o SimpleXML, acessa-o assim $item->DataContent->body->{'body.content'}.
Jesse Kochis
2
As variáveis ​​PHP podem assumir qualquer caractere quando usadas dessa maneira, até espaços e novas linhas.
Novato
Isso seria muito útil ao usar no SimpleXML ... impressionante. Obrigado por compartilhar.
KyleFarris 02/09/11
34

A sintaxe HEREDOC é o meu recurso oculto favorito. Sempre difícil de encontrar, pois você não pode procurar no Google <<<, mas impede que você escape grandes pedaços de HTML e ainda permite que você solte variáveis ​​no fluxo.

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;
Pablo Livardo
fonte
2
HEREDOC é minha maneira favorita de criar e usar instruções SQL.
bdl
11
Nota: a MOE de fechamento; não pode ser recuado.
Micahwittman
Bom, mas inútil se você usar modelos. Além disso, atrapalha a identificação adequada.
Manos Dilaverakis
7
Meu Deus, esse é o código mais feio que eu já vi. Se você estiver usando o HEREDOC, não separou a apresentação da lógica.
Lotus Notes
@Byron: Você não precisa usá-lo para apresentação, ele pode ser usado para qualquer string. Veja o comentário de bdl.
Tom Pažourek
34

Provavelmente muitos não sabem que é possível especificar constantes "variáveis" como valores padrão para parâmetros de função:

function myFunc($param1, $param2 = MY_CONST)
{
//code...
}

Strings podem ser usadas como se fossem matrizes :

$str = 'hell o World';
echo $str; //outputs: "hell o World"

$str[0] = 'H';
echo $str; //outputs: "Hell o World"

$str[4] = null;
echo $str; //outputs: "Hello World"
jamolkhon
fonte
3
Esse último é bacana. Embora eu não tenha idéia de quando seria melhor do que algum outro método para remover um personagem. +1 no entanto
George Mauer
3
Provavelmente é mais eficiente do que chamar uma função para fazê-lo. As strings são normalmente armazenadas contiguamente na memória, portanto, chegar a $ str [4] é trivial. Armazenar cadeias como matrizes de caracteres é comum à maioria das línguas que derivam de C.
sjobe
1
Você não precisa usar uma constante definida como valor padrão. O seguinte também é perfeitamente válido: function foot ($ param1, $ default = array ('chave' => 'valor'), $ default_s = 'String', $ default_i = 10, $ default_b = false). No entanto, você está correto ao observar que não pode usar uma variável como argumento padrão.
dcousineau 23/06/09
@dcousineau Seu exemplo é perfeitamente válido, pois array () não é uma função, mas uma construção de linguagem. Chamadas de função não são permitidas como valores padrão para argumentos.
21909 Jamol
4
Cuidado ao tratar as strings como matrizes se você tiver strings de vários bytes (idiomas estrangeiros, etc.)
philfreo
33

A coisa mais útil sobre o código PHP é que, se eu não entender uma função, vejo que posso procurar usando um navegador e digitando:

http://php.net/function

No mês passado, vi a função "range" em algum código. É uma das centenas de funções que eu nunca consegui usar, mas que são realmente úteis:

http://php.net/range

Esse URL é um alias para http://us2.php.net/manual/en/function.range.php . Essa ideia simples, de mapear funções e palavras-chave para URLs , é incrível.

Desejo que outras linguagens, estruturas, bancos de dados, sistemas operacionais tenham um mecanismo tão simples para procurar a documentação.

artlung
fonte
5
range()pode ser útil paraforeach( range(1, 10) as $i) { };
alex
Se você possui o FireFox; basta digitar PHP functionna barra de endereço que fará uma pesquisa do Google 'estou com sorte' e você quase sempre acaba na página de documentação php correta.
Kolky 18/03/10
30

Comentários de bloqueio rápido

/*
    die('You shall not pass!');
//*/


//*
    die('You shall not pass!');
//*/

Esses comentários permitem alternar se um bloco de código for comentado com um caractere.

Sam152
fonte
14
Isso não é realmente específico do PHP. Isso funciona em qualquer idioma que suporte // ...comentários de linha e /* ... */bloqueie comentários.
22139 Jordan Ryan Moore
quaisquer utilitários de limpeza de código acabam odiando você por usar isso ...;)
Talvi Watia
3
Eu também usei /** /antes e /**/depois. Você pode alternar o bloco removendo e adicionando o espaço no primeiro. Isso tem um benefício adicional de trabalhar com CSS (e outros idiomas que não suportam // ... comentários).
kingjeffrey
FWIW, link para o artigo original aleembawany.com/2009/01/27/lazy-block-comment-trick
aleemb
@aleemb, evite fazer mais edições nesta pergunta.
Sam152
29

Minha lista .. a maioria deles se encaixa mais nos "recursos ocultos" do que nos "recursos favoritos" (espero!), E nem todos são úteis, mas ... sim.

// swap values. any number of vars works, obviously  
list($a, $b) = array($b, $a);

// nested list() calls "fill" variables from multidim arrays:  
$arr = array(  
  array('aaaa', 'bbb'),  
  array('cc', 'd')  
);  
list(list($a, $b), list($c, $d)) = $arr;  
echo "$a $b $c $d"; // -> aaaa bbb cc d  

// list() values to arrays  
while (list($arr1[], $arr2[], $arr3[]) = mysql_fetch_row($res)) { .. }  
// or get columns from a matrix  
foreach($data as $row) list($col_1[], $col_2[], $col_3[]) = $row;

// abusing the ternary operator to set other variables as a side effect:  
$foo = $condition ? 'Yes' . (($bar = 'right') && false) : 'No' . (($bar = 'left') && false);  
// boolean False cast to string for concatenation becomes an empty string ''.  
// you can also use list() but that's so boring ;-)  
list($foo, $bar) = $condition ? array('Yes', 'right') : array('No', 'left');

Você também pode aninhar operadores ternários, às vezes é útil.

// the strings' "Complex syntax" allows for *weird* stuff.  
// given $i = 3, if $custom is true, set $foo to $P['size3'], else to $C['size3']:  
$foo = ${$custom?'P':'C'}['size'.$i];  
$foo = $custom?$P['size'.$i]:$C['size'.$i]; // does the same, but it's too long ;-)  
// similarly, splitting an array $all_rows into two arrays $data0 and $data1 based  
// on some field 'active' in the sub-arrays:  
foreach ($all_rows as $row) ${'data'.($row['active']?1:0)}[] = $row;

// slight adaption from another answer here, I had to try out what else you could  
// abuse as variable names.. turns out, way too much...  
$string = 'f.> <!-? o+';  
${$string} = 'asdfasf';  
echo ${$string}; // -> 'asdfasf'  
echo $GLOBALS['f.> <!-? o+']; // -> 'asdfasf'  
// (don't do this. srsly.)

${''} = 456;  
echo ${''}; // -> 456  
echo $GLOBALS['']; // -> 456  
// I have no idea.  

Certo, vou parar por agora :-)


Hmm, já faz um tempo ..

// just discovered you can comment the hell out of php:
$q/* snarf */=/* quux */$_GET/* foo */[/* bar */'q'/* bazz */]/* yadda */;

Assim, acabamos de descobrir que você pode passar qualquer string como um nome de método, se você a incluir entre colchetes. Você não pode definir nenhuma string como um método, mas pode capturá-las com __call () e processá-las ainda mais, conforme necessário. Hummm ....

class foo {
  function __call($func, $args) {
    eval ($func);
  }
}

$x = new foo;
$x->{'foreach(range(1, 10) as $i) {echo $i."\n";}'}();

Encontrei esta pequena jóia nos comentários do Reddit:

$foo = 'abcde';
$strlen = 'strlen';
echo "$foo is {$strlen($foo)} characters long."; // "abcde is 5 characters long."

Você não pode chamar funções dentro de {} diretamente assim, mas pode usar variáveis-holding-the-function-name e chamá-las! (* e * você também pode usar variáveis ​​variáveis)

MSpreij
fonte
2
Por favor, não use demais o operador de comparação ternário; isso leva à ofuscação do código.
staticsan
Uau. Isso pode manejar totalmente sua lista de $ GLOBALS. Má prática. Seriamente.
Talvi Watia
Já existe um concurso ofuscado de PHP?
Lotus Notes
Bem, truque com swap - impressionante e útil, obrigado.
OZ_
1
${''} = 456;hahaha .... bastante abuso.
Skurmedel
26

Manipulação de matriz.
Toneladas de ferramentas para trabalhar e manipular matrizes. Pode não ser exclusivo do PHP, mas nunca trabalhei com uma linguagem que facilitasse as coisas.

MattBelanger
fonte
como o que por exemplo? Parece-me que todas as funções são desajeitadamente nomeadas e posicionadas no espaço de nomes global. Além disso, eu não consigo pensar em isso é qualquer coisa não tão fácil em outro idioma, exceto para talvez $ arr [] = $ newvalue para adicionar valores - isso é legal
George Mauer
8
Bem, o array PHP é uma estrutura de dados que pode ser usada facilmente como uma pilha, fila, fila, lista, hashtable etc. É bastante flexível, de fato, para as necessidades mais comuns, sem recorrer a qualquer outra coisa que não seja funções array_ *.
Camilo Díaz Repka
6
O Python faz matrizes (como listas e tuplas) muito melhor que o PHP.
php demais
26

Sou um pouco como você, codigo PHP há mais de 8 anos. Eu tive que fazer um curso .NET / C # há um ano e gostei muito da linguagem C # (odiava o ASP.NET), mas isso me tornou um desenvolvedor PHP melhor.

O PHP como linguagem é muito ruim, mas sou extremamente rápido com ele e a pilha LAMP é incrível. O produto final supera em muito a soma das peças.

Dito isto, em resposta à sua pergunta:

http://uk.php.net/SPL

Eu amo o SPL , a classe de coleção em C # era algo que eu gostei assim que comecei. Agora eu posso comer meu bolo e comê-lo.

Andrew

Andrew Taylor
fonte
24

Estou um pouco surpreso que ninguém tenha mencionado isso ainda, mas um dos meus truques favoritos com matrizes é usar o operador plus. É um pouco como, array_merge()mas um pouco mais simples. Eu descobri que geralmente é o que eu quero. Com efeito, ele pega todas as entradas no RHS e as faz aparecer em uma cópia do LHS, sobrescrevendo conforme necessário (ou seja, não é comutativo). Muito útil para iniciar com uma matriz "padrão" e adicionar alguns valores reais em uma ocorrência, deixando valores padrão no lugar para valores não fornecidos.

Exemplo de código solicitado:

// Set the normal defaults.
$control_defaults = array( 'type' => 'text', 'size' => 30 );

// ... many lines later ...

$control_5 = $control_defaults + array( 'name' => 'surname', 'size' => 40 );
// This is the same as:
// $control_5 = array( 'type' => 'text', 'name' => 'surname', 'size' => 40 );
staticsan
fonte
$defaultsdeve ser$control_defaults
diEcho
3
Eu acho que não é tão claro quanto array_merge quando você tem muito código para manter. Pelo menos, quando você usa a função array_merge, é evidente que você está lidando com matrizes.
Sylvain
E esse fato que você está fazendo ... + array( ...não é suficiente para apontar isso? :-)
staticsan
Qual versão do PHP você precisa para isso?
Lotus Notes
Esse é um ótimo recurso e deve ser observado que a matriz no lado "direito" do "+" não substituirá as chaves existentes da matriz no lado "esquerdo" do "+".
Wil Moore III
21

Aqui está um, eu gosto de como definir valores padrão em parâmetros de função que não são fornecidos é muito mais fácil:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }
George Mauer
fonte
4
Curiosamente, vi esse "recurso oculto" no Google Reader na semana passada. Eu não entendo o que está oculto sobre isso - é uma sintaxe básica. Tente se ($ var = true), por exemplo.
Ross
8
Mais fácil do que o que? A maioria dos idiomas possui esse recurso.
Christian Daven
10
Mais fácil do que C # (e eu acho que C ++ e Java)
George Mauer
8
C ++ suporta valores de parâmetro padrão.
Sjobe
2
c # não suporta valores padrão. você tem que escrever uma função sobrecarregada e sempre declarar o valor que é simplesmente complicado
DeveloperChris
21

Rápido e sujo é o padrão.
A linguagem é preenchida com atalhos úteis. Isso faz do PHP o candidato perfeito para projetos (pequenos) que têm um curto tempo de lançamento no mercado. Não que o código PHP limpo seja impossível, é preciso apenas algum esforço e experiência extras.

Mas eu amo PHP porque me permite expressar o que quero sem digitar um ensaio.

PHP:

if (preg_match("/cat/","one cat")) {
   // do something
}

JAVA:

import java.util.regex.*;
Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat")
if (m.find()) {
  // do something
}

E sim, isso inclui não digitar Int .

Bob Fanger
fonte
4
você deve usar strpos vez: if (falsa == strpos ( "um gato", "gato")!) {
OIS
17
@OIS, o objetivo de seu exemplo era ilustrar e comparar a execução de uma correspondência rápida de expressões regulares, não como encontrar a string "cat" em "one cat".
dcousineau
19
Java: if (Pattern.matches ("cat", "one cat")) {// faça algo} Pare de reclamar sobre java se você não o conhece.
Uísque
3
+1 Como você preg_replace ('/ ([<[]! - \ s *) (\ S *?) (\ S * - [>]]?) / Se', "\ $ this- > Escolha ('\\ 1', '\\ 2', '\\ 3', \ $ data) ", $ text); em Java? Ele encontra um comentário no texto de entrada e chama uma função com os elementos correspondentes que, neste caso, $ this-> choose (...) decidem com o que substituir a correspondência e retornam os resultados.
DeveloperChris
1
Regex é PHP é muito ruim ... Eu prefiro ter o Regex no estilo Perl ou JavaScript, onde //está embutido na linguagem.
Cdmckay