Estou ciente de que instanceof
é um operador e que is_a
é um método.
O método tem desempenho mais lento? O que você prefere usar?
Estou ciente de que instanceof
é um operador e que is_a
é um método.
O método tem desempenho mais lento? O que você prefere usar?
Respostas:
Atualizar
A partir do PHP 5.3.9 , a funcionalidade do
is_a()
mudou. A resposta original abaixo afirma queis_a()
deve aceitar umObject
como o primeiro argumento, mas as versões do PHP> = 5.3.9 agora aceitam um terceiro argumento booleano opcional$allow_string
(o padrão éfalse
) para permitir comparações de nomes de classes de string:A principal diferença no novo comportamento entre
instanceof
eis_a()
é queinstanceof
sempre verifica se o destino é um objeto instanciado da classe especificada (incluindo as classes estendidas), ao passo queis_a()
apenas exige que o objeto seja instanciado quando o$allow_string
argumento estiver definido como o valor padrão defalse
.Original
Na verdade,
is_a
é uma função, enquantoinstanceof
é uma construção da linguagem.is_a
será significativamente mais lento (já que possui toda a sobrecarga de execução de uma chamada de função), mas o tempo geral de execução é mínimo em qualquer método.Ele não é mais descontinuado a partir da versão 5.3, portanto não há nenhuma preocupação lá.
Há uma diferença no entanto.
is_a
sendo uma função leva um objeto como parâmetro 1 e uma string (variável, constante ou literal) como parâmetro 2. Portanto:instanceof
usa um objeto como parâmetro 1 e pode usar um nome de classe (variável), instância de objeto (variável) ou identificador de classe (nome da classe gravado sem aspas) como parâmetro 2.fonte
is_a
não foi reprovado?$class = 'Foo'; var_dump($obj instanceof $class);
is_a
oinstanceof
operador vs é queis_a
aceitará expressões para o segundo parâmetro, enquanto instanceof não. Por exemplo,is_a($object, 'Prefix_'.$name)
obras enquanto$object instanceof 'Prefix_'.$name
nãois_a
nunca deveria ter sido preterido em primeiro lugar. É um pouco tarde para consertar agora. O problema é que oinstanceof
operador lança erros de sintaxe no PHP 4 e, comois_a
foi preterido no momento exato em que o operador foi introduzido, tornou-se impossível escrever código para o PHP 4 e 5 sem gerar um E_STRICT. Você não pode sequer fazerif (version_compare(PHP_VERSION, 5) >= 0) { /* use instanceof */ } else { /* use is_a */ }
porque ainda iria causar um erro de sintaxe no PHP 4.Aqui estão os resultados de desempenho de is_a () e instanceof :
A fonte de teste está aqui .
fonte
php 7
não há diferença.instanceof
pode ser usado com outras instâncias de objeto, o nome da classe ou uma interface.Eu não acho que(Atualização: consulte https://gist.github.com/1455148 )is_a()
funcione com interfaces (apenas uma string representando um nome de classe), mas me corrija se isso acontecer.Exemplo do php.net :
saídas:
fonte
is_a
faz o trabalho com interfaces da mesma forma queinstanceof
(eu ia dizer a mesma coisa, mas eu verifiquei antes de enviar, e ele faz, de facto trabalho) ...Em relação à resposta de ChrisF,
is_a()
não é mais preterido a partir do PHP 5.3.0. Acho que é sempre mais seguro procurar a fonte oficial para coisas assim.Com relação à sua pergunta, Daniel, não posso dizer sobre as diferenças de desempenho, mas parte disso se resume à legibilidade e com a qual você acha mais fácil trabalhar.
Além disso, há alguma discussão sobre a confusão em torno negando uma
instanceof
verificação vsis_a()
. Por exemplo, parainstanceof
você faria:vs o seguinte para
is_a()
:ou
Editar Parece que ChrisF excluiu sua resposta, mas a primeira parte da minha resposta ainda permanece.
fonte
Além da velocidade, outra diferença importante é como eles lidam com casos extremos.
Portanto, is_a () destaca possíveis erros enquanto instanceof os suprime.
fonte
A otimização é mínima. E as micro-otimizações nunca são uma resposta muito boa, diante da legibilidade, compreensão e estabilidade do código.
(Pessoalmente, prefiro instanceof , mas a escolha é sua;))
A principal diferença é a possibilidade de usar o nome direto da classe com instanceof
é mais curto que
(ok ... não é trivial.)
A coloração sintaxe entre instanceof (estrutura da linguagem) e is_a também é útil (para mim). deixando a função cor para operações maiores. E para uso único em if, instanceof não precisa de mais parênteses.
Nota: é claro que, em vez de MyClass :: class, você pode usar uma string direta mais curta:
Mas usar seqüência direta em um código não é uma boa prática .
A coleta sintaxe é melhor e mais útil se você puder fazer a diferença entre nomes simples de sequência e de classe. E é mais fácil alterar os nomes com o nome da classe constante. Especialmente se você usar espaço para nome com alias.
Então, por que usar is_a () ?
Pela mesma razão: legibilidade e incompreensibilidade. (a escolha é sua) Especialmente quando usado com ! ou outros operadores booleanos: is_a parece mais prático entre parênteses.
é mais legível que:
Outro bom motivo é quando você precisa usar o retorno de chamada nas funções. (como array_map ...) instanceof não é uma função, é uma construção de linguagem, portanto você não pode usá-lo como retorno de chamada.
Nesses casos, is_a pode ser útil
fonte
Não posso falar por desempenho - ainda não medi nada - mas, dependendo do que você está tentando, há limitações
instanceof
. Confira minha pergunta, recentemente, sobre isso:PHP 'instanceof' falhando com constante de classe
Acabei usando
is_a
. Gosto mais da estruturainstanceof
(acho melhor) e continuarei a usá-la onde puder.fonte
Aqui estão os resultados de desempenho obtidos aqui :
instanceof
é mais rápido.Funções
Vezes (executado 5000 vezes cada)
fonte
Há um cenário em que apenas
is_a()
funciona einstanceof
falhará.instanceof
espera um nome de classe literal ou uma variável que seja um objeto ou uma string (com o nome de uma classe) como seu argumento correto.Mas se você deseja fornecer a sequência de um nome de classe a partir de uma chamada de função, ela não funcionará e resultará em um erro de sintaxe.
No entanto, o mesmo cenário funciona bem
is_a()
.Exemplo:
Isso é baseado no PHP 7.2.14.
fonte