Estou construindo uma biblioteca ORM com reutilização e simplicidade em mente; tudo vai bem, exceto que fiquei preso por uma limitação de herança estúpida. Considere o código abaixo:
class BaseModel {
/*
* Return an instance of a Model from the database.
*/
static public function get (/* varargs */) {
// 1. Notice we want an instance of User
$class = get_class(parent); // value: bool(false)
$class = get_class(self); // value: bool(false)
$class = get_class(); // value: string(9) "BaseModel"
$class = __CLASS__; // value: string(9) "BaseModel"
// 2. Query the database with id
$row = get_row_from_db_as_array(func_get_args());
// 3. Return the filled instance
$obj = new $class();
$obj->data = $row;
return $obj;
}
}
class User extends BaseModel {
protected $table = 'users';
protected $fields = array('id', 'name');
protected $primary_keys = array('id');
}
class Section extends BaseModel {
// [...]
}
$my_user = User::get(3);
$my_user->name = 'Jean';
$other_user = User::get(24);
$other_user->name = 'Paul';
$my_user->save();
$other_user->save();
$my_section = Section::get('apropos');
$my_section->delete();
Obviamente, esse não é o comportamento que eu esperava (embora o comportamento real também faça sentido). Minha pergunta é se vocês sabem de um meio de obter, na classe pai, o nome da classe filha.
php
inheritance
static-methods
Saalaa
fonte
fonte
debug_backtrace()
.. Uma possível solução seria usar vinculação estática tardia do PHP 5.3, mas isso não é uma possibilidade no meu caso. Obrigado.Você não precisa esperar pelo PHP 5.3 se for capaz de conceber uma maneira de fazer isso fora de um contexto estático. No php 5.2.9, em um método não estático da classe pai, você pode fazer:
e ele retornará o nome da classe filha como uma string.
ie
isso resultará em:
doce hein?
fonte
$x = new Parent();
deveria ser$x = new Child();
.Eu sei que essa questão é muito antiga, mas para quem procura uma solução mais prática do que definir uma propriedade em cada classe contendo o nome da classe:
Você pode usar a
static
palavra - chave para isso.Conforme explicado nesta nota de contribuição na documentação php
Exemplo:
fonte
static()
é o caminho a percorrer!Eu sei que é um post antigo, mas quero compartilhar a solução que encontrei.
Testado com PHP 7+ Use o link de função
get_class()
O exemplo acima resultará em:
fonte
Caso você não queira usar get_called_class (), você pode usar outros truques de vinculação estática tardia (PHP 5.3+). Mas a desvantagem, neste caso, é o método getClass () em cada modelo. O que não é grande coisa, IMO.
fonte
Parece que você está tentando usar um padrão singleton como padrão de fábrica. Eu recomendaria avaliar suas decisões de design. Se um singleton realmente for apropriado, eu também recomendaria usar apenas métodos estáticos onde a herança não é desejada.
fonte
Talvez isso não esteja realmente respondendo à pergunta, mas você pode adicionar um parâmetro para get () especificando o tipo. então você pode ligar
em vez de chamar User :: get (). Você poderia adicionar lógica em BaseModel :: get () para verificar se um método get existe na subclasse e então chamá-lo se quiser permitir que a subclasse o substitua.
Caso contrário, a única maneira que consigo pensar é, obviamente, adicionando coisas a cada subclasse, o que é estúpido:
Isso provavelmente seria interrompido se você subclasse User, mas suponho que você possa substituir
get_parent_class(__CLASS__)
por'BaseModel'
nesse casofonte
O problema não é uma limitação de idioma, é seu design. Não importa se você tem aulas; os métodos estáticos desmentem um projeto procedural em vez de orientado a objetos. Você também está usando o estado global de alguma forma. (Como
get_row_from_db_as_array()
saber onde encontrar o banco de dados?) E, finalmente, parece muito difícil fazer um teste de unidade.Experimente algo nesse sentido.
fonte
Duas variações da resposta de Preston:
1)
2)
Observação: iniciar um nome de propriedade com _ é uma convenção que basicamente significa "eu sei que tornei isso público, mas realmente deveria ter sido protegido, mas eu não poderia fazer isso e atingir meu objetivo"
fonte