Comments 28
А что, в пыхпыхе «наследуются» статические методы?
0
Незнаю, если совсем уж любое решение — можно через debug_backtrace выдирать имя, по которому метод был вызван, ну и соот-но explode('::', $имя_метода);
+2
Как? У меня не получилось. Кстати, условие такое, что класс Product должен быть пустым, т.е. без методов и свойств.
0
Ну если совсем уж любое решение подойдет — тогда можно продолжить мысль, debug_backtrace не присылает имя дочернего класса, зато присылает имя файла и номер строки, где все это дело вызывается, можно вырезать имя дочернего класса оттуда :) Что-то вроде:
public static function find() {
list($aTrace) = debug_backtrace();
$aFile = file($aTrace['file']);
$sLine = $aFile[$aTrace['line'] — 1];
$iEnd = strpos($sLine, $aTrace['type'].$aTrace['function']);
echo substr($sLine, 0, $iEnd);
}
В данном конкретном примере правда обрезается только конец строки, если сначала перед вызовом будет — тоже попадет в имя, для полностью рабочего состояния нужно еще помудрить :)
public static function find() {
list($aTrace) = debug_backtrace();
$aFile = file($aTrace['file']);
$sLine = $aFile[$aTrace['line'] — 1];
$iEnd = strpos($sLine, $aTrace['type'].$aTrace['function']);
echo substr($sLine, 0, $iEnd);
}
В данном конкретном примере правда обрезается только конец строки, если сначала перед вызовом будет — тоже попадет в имя, для полностью рабочего состояния нужно еще помудрить :)
+2
Во, полная версия моего монстрообразного креатива :) Скорость работы данной конструкции будет воистину коллосальной :)
public static function find() {
list($aTrace) = debug_backtrace();
$aFile = file($aTrace['file']);
$sLine = $aFile[$aTrace['line'] — 1];
$iEnd = strpos($sLine, $aTrace['type'].$aTrace['function']);
$sLine = substr($sLine, 0, $iEnd);
$sToken = strtok($sLine, '( .=&|');
while($sToken) {
$sName = $sToken;
$sToken = strtok('( .=&|');
}
return $sName;
}
public static function find() {
list($aTrace) = debug_backtrace();
$aFile = file($aTrace['file']);
$sLine = $aFile[$aTrace['line'] — 1];
$iEnd = strpos($sLine, $aTrace['type'].$aTrace['function']);
$sLine = substr($sLine, 0, $iEnd);
$sToken = strtok($sLine, '( .=&|');
while($sToken) {
$sName = $sToken;
$sToken = strtok('( .=&|');
}
return $sName;
}
0
Тьфу, извиняюсь, даже так нельзя :)
+1
Можно пробовать через debug_backtrace(), но лучше, наверное, подождать «static::».
0
Вот, сделал грязнющий хак. Конечно, так делать нельзя, но я сделал, чисто для эксперимента.
Выведет: Product
class Model_Base {
public static function get_sub_class_name() {
foreach (array_reverse(get_declared_classes()) as $classname) {
if (is_subclass_of(new $classname, get_class())) {
return $classname;
break;
}
}
}
public static function find() {
return self::get_sub_class_name();
}
}
class Product extends Model_Base {
}
echo Product::find();
* This source code was highlighted with Source Code Highlighter.
Выведет: Product
0
Тоже блин вариант :) Даже незнаю что будет работать быстрее, мой способ или ваш, хотя это конечно от количества классов зависит :) скорее всего всетки ваш.
0
И если вы добавите ещё один класс, который наследуется от Model_Base, то ваш код не будет работать правильно.
0
Во-первых, вызывая метод статически, Вы по-любому знаете имя класса, иначе Вы не сможете его вызывать.
Во-вторых, статические методы они вызываются для того класса, для которого они определены, в данном случае, сколько бы раз вы не унаследовали, при вызове find, всё одно окажетесь в классе Model_Base
Если убрать все статики, то будет как надо:
Во-вторых, статические методы они вызываются для того класса, для которого они определены, в данном случае, сколько бы раз вы не унаследовали, при вызове find, всё одно окажетесь в классе Model_Base
Если убрать все статики, то будет как надо:
<?php
class Model_Base {
public function find() {
return get_class($this);
}
}
class Product extends Model_Base { }
$obj = new Product();
echo $obj->find();
* This source code was highlighted with Source Code Highlighter.
0
Если вам нужно имя класса — у вас плохая архитектура (с) Буч
+5
Я задавал 2 недели на phpclub ЭТОТ же вопрос.
Просто решил все перепроектированием.
Вывод такой: наследование и статические методы практически несовместимы.
Просто решил все перепроектированием.
Вывод такой: наследование и статические методы практически несовместимы.
0
webest.net/2005/04/18/kak-prostrelit-sebe-nogu.php
-2
>>>Реально ли в PHP 5.2 получить имя подкласса (т.е. Product) в статическом методе find() класса Model_Base?
Да реально:
class Model_Base {
public static function find() {
return get_class();
}
}
class Product extends Model_Base {
public static function find() {
return get_class();
}
}
echo Product::find();
Да реально:
class Model_Base {
public static function find() {
return get_class();
}
}
class Product extends Model_Base {
public static function find() {
return get_class();
}
}
echo Product::find();
-2
в статическом методе find() класса Model_Base?
Вы по-моему невнимательно читали условие задачи.
0
афтор видимо невнимательно читал мануалы по ООП для пэхэпэ, и неправильно сформулировал задачу.
-1
афтар хочет прострелить себе ногу, а не руку. не путайте его ;-)
0
Совсем нет. Наоборот, пытаюсь улучшить себе процесс кодинга. Для ORM решение этой задачи было бы полезно, мне не пришлось бы каждый раз создавать новый экземпляр класса, что сэкономило бы врямя и было бы более читаемо (смотрим, как в ActiveRecord для Ruby сделано).
Но в php подобное можно будет сделать только начиная с 5.3. Поэтому — ждем.
Но в php подобное можно будет сделать только начиная с 5.3. Поэтому — ждем.
0
угу, в процедурном программировании вообще не надо объектов создавать =)
покажи свой нечитаемый код, хоть.
покажи свой нечитаемый код, хоть.
0
find('Product', ...) Model_find('Product', ...) Model::find('Product', ...)
Cделать что нибуть в этом роде — религия не позволяет?
Нет веть обязательно нужен синтаксический сахар, о да… потомучто вот в другом езыке так сделано… да будем ждать когда же блять наконец разработчики соизволят добавить очень нужную фичу…
Cделать что нибуть в этом роде — религия не позволяет?
Нет веть обязательно нужен синтаксический сахар, о да… потомучто вот в другом езыке так сделано… да будем ждать когда же блять наконец разработчики соизволят добавить очень нужную фичу…
0
Сделал так:
$p = new Product;
// Получаем объект rowset
$rowset = $p->find('all');
$p = new Product;
// Получаем объект rowset
$rowset = $p->find('all');
0
Sign up to leave a comment.
Получение имени подкласса