Ao desenvolver um plug-in, as funções devem ser agrupadas em uma Classe para evitar conflitos de namespace?
O uso de classes cria sobrecarga de desempenho para PHP?
Se houver um impacto no desempenho, os nomes das funções devem ser pré-fixados?
Ao desenvolver um plug-in, as funções devem ser agrupadas em uma Classe para evitar conflitos de namespace?
O uso de classes cria sobrecarga de desempenho para PHP?
Se houver um impacto no desempenho, os nomes das funções devem ser pré-fixados?
Respostas:
Ao desenvolver um plug-in, as funções devem ser agrupadas em uma Classe para evitar conflitos de namespace?
Sim, mas esse é apenas um dos argumentos menores. De fato, essa não é a natureza "verdadeira" de uma classe no OOAD .
O uso de classes cria sobrecarga de desempenho para PHP?
Não, notavelmente. O design inadequado e / ou o código escrito incorreto ou a otimização antecipada criam muito mais problemas de desempenho do que os recursos reais do idioma.
Se houver um impacto no desempenho, os nomes das funções devem ser pré-fixados?
Como está escrito, não há desempenho atingido. Um código gravado incorreto será mais prejudicial ao desempenho do que um código gravado que possui mais linhas de código, mas não o força a fazer coisas ruins.
Bottom Line:
Você pode usar classes de maneira diferente para plug-ins. Você pode apenas usá-los para ter algum tipo de espaço para nome e usá-los "apenas" para funções globais. A forma mais direta disso são funções de classe estática, o seguinte exemplo de código mostra as duas primeiras funções globais e depois as funções de classe estática global:
/* global function */
function myplug_hook()
{
}
add_filter('the_hook', 'myplug_hook');
/* global static function */
class myplug
{
public static function hook()
{
}
}
add_filter('the_hook', 'myplug::hook');
Este é apenas um pequeno exemplo mostrando que você precisa digitar mais para o gancho único. Além disso, ele mostra como o namespacing funciona: Você pode substituir com mais facilidade o nome de classe única para renomear todas as funções estáticas e, em seguida, procurar e substituir myplug::
quais seriam mais difíceis myplug_
devido a falsos positivos. Mas no final não há muita diferença.
O ponto principal é: funções estáticas de classe Docs não são muito mais do que funções globais Docs .
E este exemplo também mostra: O namespacing é bom, mas com worpdress, o namespacing para com o uso de hooks: A função de retorno de chamada é codificada, portanto, o benefício no namespacing usando a classe (um local para o nome base, o nome da classe) não ajuda quando você intervém seu código com o wordpress para os nomes dos ganchos.
O benefício real começa com o uso de instâncias de classe reais e funções não estáticas. Isso tem o benefício de que você pode começar a usar os princípios OO e pode otimizar seu código. Funções de classe estática são mais um problema do que uma solução.
Então é mais do que apenas açúcar sintático.
O ponto principal é: faça algo que o ajude a escrever o código com o qual você possa lidar e manter facilmente. Não exagere no desempenho, isso é um erro comum. Mais importante é que você escreva um código fácil de ler e entender, que faça exatamente o que você precisa. Talvez esta pergunta e resposta sejam úteis para uma imagem maior neste contexto: Ajuda múltipla da Metabox personalizada .
Uma abordagem comum que tenho, mesmo com plug-ins menores, é usar uma função auxiliar estática para instanciar o plug-in e o restante reside na instância do plug-in. Isso ajuda a encapsular a lógica principal do plug-in e se beneficia do espaçamento de nomes com os ganchos, assim como membros privados podem ser reutilizados entre ganchos, o que não é possível com as funções globais padrão. O seguinte exemplo de código mostra o padrão:
<?php
/** Plugin Headers ... */
return MyPlugin::bootstrap();
class MyPlugin
{
/** @var MyPlugin */
static $instance;
static public function bootstrap() {
if (NULL === self::$instance) {
self::$instance = new __CLASS__;
}
return self::$instance;
}
# ...
}
Esse é um padrão comum que eu uso para o arquivo de plug-in base. A classe de plug-ins, por um lado, representa o plugin para wordpress e, por outro lado, permite começar a usar paradigmas orientados a objetos para o próprio código, que pode até ser completamente orientado a objetos (mas não precisa). É uma espécie de controlador, interagindo com toda a API do wordpress como o (s) pedido (s).
Como o exemplo mostra, uma instância do plugin será criada. Isso permite que você faça uso de bens comuns conhecidos como um Docs do Construtor ( )__construct
para inicializar o plug-in real:
# ...
class MyPlugin
{
# ...
public function __construct()
{
add_filter('the_hook', array($this, 'hook'));
}
public function hook()
{
}
# ...
}
No momento em que o gancho é registrado, este objeto de plug-in já se beneficia do seu design: você deixou de codificar a função de gancho real com base no nome da classe do plug-in concreto . Isso é possível devido à ligação da classe à instância do objeto para o retorno de chamada. Parece complicado, apenas dizendo: $this
é o plugin. Pode ser usado em retornos de chamada de gancho, compare os métodos da classe Registering como retornos de chamada de gancho .
Esse padrão permite uma interface mais fácil com o wordpress: a injeção é reduzida aos nomes dos ganchos e a quais dados eles fornecem. Você pode começar a implementar diretamente nesta classe de plug-in ou refatorar sua implementação, portanto, coloque apenas código na classe de plug-in que é o mínimo necessário para definir sua interface de plug-ins contra o wordpress, mas mantenha a lógica geral à parte do worpdress. É aqui que a diversão começa e provavelmente o que cada autor de plug-in deseja alcançar a longo prazo.
Portanto, não programe com worpdress, mas contra ela. Como o worpdress é bastante flexível, não há uma interface comum ou fácil de descrever para a qual programar. Uma classe de plug-in base pode assumir essa função, permitindo mais flexibilidade para seu próprio código, o que levará a um código mais fácil e a um melhor desempenho.
Portanto, há mais do que apenas um benefício no espaçamento de nomes. A melhor sugestão que posso dar é: Tente você mesmo. Não há muito a perder, apenas coisas novas a descobrir.
Você provavelmente notará diferenças depois de passar por algumas atualizações importantes do wordpress, mantendo seu plugin compatível.
Advertência : Se o seu plug-in se integra diretamente ao wordpress para fazer o trabalho, usar uma ou duas funções públicas pode ser mais adequado para você. Pegue a ferramenta certa para o trabalho.
return $myPlugin = new MyPlugin();
também. No entanto, para uma visão mais ampla, um simples novo pode não ser suficiente, compare o Plugin do WordPress: Como evitar o "acoplamento apertado"? .
Geral: Afaik, não há diferença no "desempenho" entre classes e conjuntos de funções.
Detalhe:
function_exists()
vs. class_exists()
como normalmente você tem muitas funções (~ 1.800 (?) No wp core) vs. classes (~ 100 (?) No wp core). Portanto, tornar as coisas "conectáveis" e, portanto, questionar a existência é uma diferença no tempo de execução.conjunto de funções: Em geral, as funções são executadas na linha que você chama. Então, toda vez que você liga para as coisas, você precisa escrevê-las novamente, se precisar chamá-las mais de uma vez.
Classe: Existem diferentes abordagens para as classes. A classe que mais se aproxima de um conjunto de funções é a classe "factory" ( wikipedia / google ). Imo é quase o mesmo que um conjunto de funções, mas encapsulado em uma classe. Mas existem outros "tipos" de classes também. Você poderia, por exemplo, escrever um resumo ou uma classe de classe pai, que você estende com uma classe filha. Em um exemplo do mundo real: digamos que você tenha uma classe que cria alguns campos de texto estático. Na sua __construct()
função, você tem um conjunto de cenários como "left_column", "right_column" e "footer_field". Então você chama algo como $text_field = new TextFieldClass();
instanciar a classe. E depois você simplesmente chama $text_field->add( $case => 'left_column', 'case' => 'foo text' );
e$text_field->add( $case => 'footer_field', 'case' => 'bar text' );
. Então todos os seus condicionais e outros já foram executados quando você instancia a classe e apenas as duas funções da classe seriam chamadas quando você cria os campos de texto. Nesse cenário, você poderia ter economizado alguns ms de tempo de execução.
Se você escrever suas aulas com sabedoria, terá uma pequena vantagem no desempenho. Mas você terá uma estrutura bem organizada para trabalhar. Até agora nada de espetacular. Mas se você considerar os seguintes casos de uso "divididos" para classes e funções em um plug-in, obterá meu ponto final : Classe é interna, funções são API . Contanto que você ofereça API apenas através de funções publicamente utilizáveis (que então chamam classes ou funções de classe), você estará no lado de salvar, desenvolvendo ainda mais seu plug-in. Você adquiriu a liberdade de alterar a estrutura interna ou mesmo as possibilidades do seu plug-in sem afetar os usuários a qualquer momento e em qualquer lugar.
Exemplo:
// construction of object
if ( ! class_exists( 'WPSE_HelloWorld' ) )
{
class WPSE_HelloWorld
{
function __construct( $args = array( 'text', 'html', 'echo' ) )
{
// call your object building procedures here
$this->hello_world( 'text', 'html', 'echo' );
}
function hello_world( 'text', 'html', 'echo' )
{
$start_el = '<{$html}>';
$end_el = '</{$html}>';
if ( $echo )
{
return print "{$start_el}{$some}{$end_el}";
}
return "{$start_el}{$some}{$end_el}";
}
} // END Class
}
// API: public functions
function the_hello_world( $args( 'echo' => true ) )
{
$new = new WPSE_HelloWorld();
return $new->hello_world( $args );
}
function get_hello_world( array( $args( 'echo' => false) ) )
{
$new = new WPSE_HelloWorld();
return $new->hello_world( $args );
}
// then you can call it like get_the_title() or the_title(), which you know from the WP API:
// 'echo' is set to false per default:
$some_var = get_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *returns* "<strong>hello reader</strong>"
// 'echo' is set to true per default:
the_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *prints/echos* "<strong>hello reader</strong>"
Nota: Leia também o link @ t310s publicado no comentário ao Q.
if( ! class_exists )
linha que você tem no início?
class_exists
verificação não porque poderia ser incluída mais de uma vez, mas para evitar um conflito com outra classe?
As aulas geralmente não oferecem benefícios em termos de desempenho, mas também raramente têm efeitos negativos. Seu benefício real é tornar o código mais claro e evitar conflitos de namespace.
Na maioria das vezes, se você usar funções, você colocará o nome do plug-in em cada nome de função; assim, duplicará esse nome uma dúzia de vezes se o plug-in tiver uma dúzia de funções, o que é um pouco chato .
Com as classes, você provavelmente terá o nome do plug-in no nome da classe provavelmente uma vez.
Além disso, você pode usar herança ou outras construções oo para implementar comportamentos de uma maneira muito limpa. Aqui está um ex:
class animalplugin{
//plugin functions...
function talk(){print "animalnoise";}
}
class animalplugin_with_cat_mods extends abcplugin{
//cat functions overrides
function talk(){print "meow";}
}
if (iscat()){
new animalplugin_with_cat_mods();
} else {
new animalplugin();
}