SmartObject
O SmartObject aprimorou o comportamento dos objetos em PHP durante muitos anos. Desde o PHP 8.4, todas as suas funcionalidades se tornaram parte nativa do próprio PHP, concluindo assim sua missão histórica como pioneiro da abordagem orientada a objetos moderna em PHP.
Instalação:
O SmartObject surgiu em 2007 como uma solução revolucionária para as limitações do modelo de objetos do PHP da época. Quando o PHP sofria com vários problemas de design orientado a objetos, ele trouxe melhorias significativas e simplificou o trabalho dos desenvolvedores. Tornou-se uma parte lendária do framework Nette. Oferecia funcionalidades que o PHP só obteria muitos anos depois – desde a validação de acesso às propriedades até o tratamento sofisticado de erros. Com a chegada do PHP 8.4, completou sua missão histórica, pois todas as suas funcionalidades se tornaram partes nativas da linguagem. Esteve à frente do desenvolvimento do PHP por notáveis 17 anos.
O SmartObject passou por uma evolução técnica interessante. Inicialmente, foi implementado como a classe
Nette\Object
, da qual outras classes herdavam a funcionalidade necessária. Uma mudança significativa veio com
o PHP 5.4, que introduziu o suporte a traits. Isso permitiu a transformação em um trait Nette\SmartObject
,
trazendo maior flexibilidade – os desenvolvedores podiam usar a funcionalidade mesmo em classes que já herdavam de outra
classe. Enquanto a classe original Nette\Object
deixou de existir com o PHP 7.2 (que proibiu nomear classes com a
palavra ‚Object‘), o trait Nette\SmartObject
continua vivo.
Vamos explorar as funcionalidades que o Nette\Object
e depois o Nette\SmartObject
ofereciam. Cada uma
dessas funções representava um passo significativo na programação orientada a objetos em PHP na época.
Estados de Erro Consistentes
Um dos problemas mais críticos do PHP inicial era o comportamento inconsistente ao trabalhar com objetos. O
Nette\Object
trouxe ordem e previsibilidade a esse caos. Vejamos como o PHP se comportava originalmente:
O fatal error terminava a aplicação sem possibilidade de reação. A escrita silenciosa em membros inexistentes sem aviso
poderia levar a erros graves difíceis de detectar. O Nette\Object
capturava todos esses casos e lançava uma
MemberAccessException
, permitindo que os programadores reagissem e tratassem esses erros:
Desde o PHP 7.0, a linguagem não causa mais fatal errors não capturáveis, e desde o PHP 8.2, o acesso a membros não declarados é considerado um erro.
Sugestão „Did you mean?“
O Nette\Object
veio com uma funcionalidade muito conveniente: sugestões inteligentes para erros de digitação.
Quando um desenvolvedor cometia um erro no nome de um método ou variável, ele não apenas relatava o erro, mas também oferecia
ajuda sugerindo o nome correto. Esta mensagem icônica, conhecida como „did you mean?“, poupou horas de busca por erros de
digitação:
Embora o PHP em si não tenha nenhuma forma de „did you mean?“, essa funcionalidade agora é fornecida pelo Tracy. E ele pode até mesmo corrigir automaticamente esses erros.
Properties com Acesso Controlado
Uma inovação significativa que o SmartObject trouxe ao PHP foram as properties com acesso controlado. Esse conceito, comum em linguagens como C# ou Python, permitiu que os desenvolvedores controlassem elegantemente o acesso aos dados do objeto e garantissem sua consistência. Properties são uma ferramenta poderosa da programação orientada a objetos. Funcionam como variáveis, mas na verdade são representadas por métodos (getters e setters). Isso permite validar entradas ou gerar valores no momento da leitura.
Para usar properties, você deve:
- Adicionar a anotação
@property <type> $xyz
à classe - Criar um getter chamado
getXyz()
ouisXyz()
, um setter chamadosetXyz()
- Garantir que o getter e setter sejam public ou protected. Eles são opcionais – assim podem existir como properties read-only ou write-only
Vejamos um exemplo prático usando a classe Circle, onde usaremos properties para garantir que o raio seja sempre não
negativo. Substituiremos public $radius
por uma property:
Desde o PHP 8.4, a mesma funcionalidade pode ser alcançada usando property hooks, que oferecem uma sintaxe muito mais elegante e concisa:
Extension Methods
O Nette\Object
trouxe outro conceito interessante ao PHP inspirado em linguagens de programação modernas –
extension methods. Essa funcionalidade, emprestada do C#, permitia que os desenvolvedores estendessem elegantemente classes
existentes com novos métodos sem modificá-las ou herdar delas. Por exemplo, você poderia adicionar um método
addDateTime()
a um formulário que adiciona um DateTimePicker personalizado:
As extension methods se mostraram impráticas porque os editores não sugeriam seus nomes e, em vez disso, relatavam que o método não existia. Portanto, seu suporte foi descontinuado. Hoje, é mais comum usar composição ou herança para estender a funcionalidade da classe.
Obtendo o Nome da Classe
O SmartObject oferecia um método simples para obter o nome da classe:
Acesso à Reflexão e Anotações
O Nette\Object
fornecia acesso à reflexão e anotações através dos métodos getReflection()
e
getAnnotation()
. Essa abordagem simplificou significativamente o trabalho com metainformações de classe:
Desde o PHP 8.0, é possível acessar metainformações através de atributos, que oferecem ainda mais possibilidades e melhor verificação de tipo:
Method Getters
O Nette\Object
oferecia uma maneira elegante de passar métodos como se fossem variáveis:
Desde o PHP 8.1, você pode usar a first-class callable syntax, que leva esse conceito ainda mais longe:
Eventos
O SmartObject oferece uma sintaxe simplificada para trabalhar com eventos. Eventos permitem que objetos informem outras partes da aplicação sobre mudanças em seu estado:
O código $this->onChange($this, $radius)
é equivalente ao seguinte loop:
Para maior clareza, recomendamos evitar o método mágico $this->onChange()
. Uma substituição prática é a
função Nette\Utils\Arrays::invoke: