powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP: Вызов static метода из метода объекта. Баг или фича?
25 сообщений из 66, страница 2 из 3
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284298
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow,

Может разжуёте КАК позднее статическое связывание может сказываться именно в этом коде? Оно ТУТ причём?
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284337
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поясню, почему тут нет никакого "позднего связывания":

1. Тут
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
function getModeSelector(array $list = null, array $params = array(... набор условий по умолчанию...) )
{
    if( !isset($list)) ) {
        $modeModel = new Model();
        $params['modelTable'] = array('cols'=>array(), 'where'=>'..', ..);
        $list = $modeModel->getData($params);
    }
    $result = array();
    foreach( $list as $num => $item) {
         $result[] = .. преобразование по набору условий из второго параметра $params;
    }
    return $result;
}



приведен вызывающий код. Который никаких объектов не создает и НЕ содержит. Обынкавенная PHP функция с двмя параметрами, имеющими каки-то значения "по умолчанию".

2. В коде стоит проверка входного параметра на наличие, и вот если его нет (null) , то только тогда создается объект класса Model, через метод которой получаются данные для второй части функции. Всё.

3. Метод объекта ->getData() описан в самом начале, в примере. Он отсутствует у класса Model, но есть в родительском классе. Совершенно нормально должен вызываться как и любой наследуемый метод.

4. Метод ->getData() внутри себя, через get_class() обращается к статическому методу но уже дочернего класса Model... опять же не вижу проблем, поскольку объект класса уже создан и метод объекта, вполне способен вызвать дочерний статический метод...

5. Метод возвращает массив результата, который замещает собой пустой параметр... в PHP нельзя присваивать значение параметру локально внутри функции???

Поясните, плиз свою иронию... или перестаньте троллить.
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284344
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109,

больше помочь - некому?
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284360
apapacy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так я думал проблема решена уже переустановкой ПЫХа. Как Вы и написали в предыдущих сообщениях.
Мне этото вопрос понравился так как не так часто приходится наблюдать завал сервака пыховским скриптом.
Но Вы уверены что ошибка локализована именно в той части кода которую Вы нам предоставили?
Я так думаю что пора дать полный архив и тогда можно и поговорить по сабжу - где может идти утечка?

Позднее связывание у Вас все равно не получится так как ПЫХ 5.2 а нужен 5.3. Непонятно почему необходимость устанавливать и даже переустанавливать именно 5.2, когда на дворе уже 5.4?
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284371
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
apapacy, да, я тоже так думал. Однако ошибался. :(

Дело в том, что сервак пашет "какое-то" время... при этом отдает всё как надо. Потом "внезапно" (и не знаю как локализовать момент), он в лог пишет ошибку "canary mismatch ... efree heap overflow... " , там указывается файл PHP который вызвал ошибку и строку.

Вот там и нашел, что ссылка из всех мест идёт именно в эту функцию. Она вызывается, конкретно на этой строке. Всего есть 5 мест где она используется. В трех местах одинапково - и именно они и фигуряют в ошибках "кучи". Код самой функции, за исключением содержимого второй части (цикла foreach) - тут.

Ещё сегодня обнаружил такую "странность" и никак не могу понять КАК такое возможно: после отвала сервера (уже выдает 502), если просто пересохранить файл с этой функцией - восстанавливает работоспособность... но опять же "на произвольное время"... ваще бред какой-то... КАК это может происходить? Стоит Zend Framework 1.7.8 (и вот покинуть его - возможности нет и ещё до меня наколбасили)... собственно классы догружаются через Zend Loader...
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284373
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
насчет "позднего связывания" - его там и нет. Базовый метод вызывает статические методы (см. первый пост) через классическую функцию get_class и calc_user_func()... "всё в лоб". :)
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284376
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
собственно "мой фреймворк" - это попытка заменить работающий ZF.
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284387
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А Вы рабочий код написали то? Спустя 5 минут всматривания в код замечаешь вот такую вещь:

Arhat109пример (как-то так):
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
// Класс подготовки sql выражения и параметров к запросу:
class Select {

    ...

    public function toString()
    {
        // формирует из массива строку запроса, тоже не вопрос.
    }
}

class Base
{
...
    static public function getSql( Select $sql, array $params ) { return false; }

    ...

    public function getData(array $params) {
        $className = get_class($this);

        $sql = call_user_func($className.'::getSql', new Select, $params); //Как написано далее, тут на выходе строка или false

        return $this->db->query($sql->toString(), $sql->bindData ); // А тут вызываем метод toString у строки или у boolean
        // (по сути тут код должен завалиться). Почему не падает? там точно так написано?
    }
}

class A extends Base {
    static function getSql( Select $sql, array $params)
    {
        ...
        return $sql->toString();  //ОБРАЩАЕМ ВНИМАНИЕ <<< ТУТ МЫ ПОЛУЧАЕМ СТРОКУ
    }
}

class B extends Base {
    static function getSql( Select $sql, array $params)
    {
        ...
        return $sql->toString();  //И ТУТ ТОЖЕ ПОЛУЧАЕМ СТРОКУ
    }
}





Насколько я помню, вызов несуществующего метода должен или обвалить скрипт, или просто вернуть null (если данная ошибка игнорируется).

Я понимаю, что не гуру никак уж. Но походу тут же ошибка или в коде, или в описаниях пропущенных частей кода. По-этому надо хоть код классов показать полностью, что бы понятно было. Кстати, а как скрипт то запускается? по крону? в фоне висит и постоянно что-то делает? по запросу юзера?
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284392
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Програмёр,

в первом посту - конечно "пример", писанный для показу идеи, да ещё и "на скорую руку", а не полностью рабочий код.

В рабочем коде пока ещё гоняются Zend_Db_Select объекты и их методы, вместо класса Select примера..
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284393
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
недочитал. Дополню:

стандартно для ZF: index.php грузит кучу его классов, в т.ч. и автолоадер и диспетчер запросов, который разбирает урл и создает объект класса "контроллер", вызывая его метод обработки запроса и передавая ему парамтеры запроса... уплощенно.

Вот эти самые методы обработки запросов (действия в терминах ZF) и вызывают эту функцию для подготовки данных к показу. Функция "всего лишь" формирует текстовку <option ..>..</option> для селекторов, в виде массива. Просто, она "умеет" формировать как простые селекторы, так и группированные, так и иерархически группированные с формированием текста опции из нескольких указанных полей выборки, соединяя их по заданному правилу.

Когда основные данные уже выбраны - она получает их, а когда их ещё нет или они не нужны - запрашивает самостоятельно по расширенному набору правил (часть к ней приходит и "так" из действия контроллера - по ним, всё одно текстовки формировать, а стало быть из БД брать - надо).
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284401
apapacy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возникают такие мысли
1) Зачем статические методы если вызываются из экземпляря всегда. Заменить на методы экземпляра
Вызов метода из строки решение явно нерациональное. Предполагаю что engine может пытаться закешировать их и переполняется.
2) Собственно query - не получается ли где-то супербольшой выборки.
3) Ну и реккурсия...
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284434
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторопять же не вижу проблем, поскольку о бъект класса уже создан и метод объекта, вполне способен вызвать дочерний статический метод...
чем дальше тем понедельник всё удачней и удачней. жги еще, пока он не кончился!

Модератор: Скаря, пора бы объяснить уже поводы для веселья, растолковать "что не так" в высказываниях оппонентов.
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284440
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109,

Хм. Ответ на вопрос то я получил, но не тот который нужен был. Ладно, тогда первые возможные соображения:
1. Скрипт запускается пользователем - ответ приходит? Сайт грузится? Скорее всего попадаете в цикл/рекурсию, в котором выделяется огромное количество ресурсов.
2. Скрипт запускается по крону - скорее всего зацикливание или бесконечная рекурсия. То есть один процесс не завершается, а второй уже запускается. Спустя некоторое время не достаточно памяти.
3. Скрипт висит в фоне - любое нерациональное использование ресурсов.

Из вышесказанного следует, что первым делом надо проверить все циклы и вызовы. Помню на yii получил бесконечную рекурсию, когда случайно вызвал одну функцию из другой, а в первой был вызов второй. Может и у Вас так же?

З.Ы. есть вариант, что представленный код не приводит к данной ошибке (ведь он не проверен). И тогда обсуждения не дадут никакого результата. По сути пой пост - это пальцем в небо :)
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284453
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109,

Кстати. По поводу фреймворка. Не знаю как в zend (думаю так же. Помню читал, что yii писали на основе zend), но в yii запрос, который Вы предложили несложно создаётся с помощью связей и критерий. Меня например он мало в чём ограничивает и чем дальше, тем больше убеждаюсь, что из-за недостаточного его познания мной.

Так что, я бы всё же пересмотрел на Вашем месте вопрос об рациональности написания своего фреймворка.
Хотя это уже вопрос насколько сильно хочется :)
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284599
Фотография r u
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109,

зачем вызывать статический метод, если вы создаете сам объект?
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284601
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow,

как известно, "сила дурака - в молчании". Продолжайте, только НЕ мешайте решать проблему... , а то все подумают что Вы - знаете решение, а это не так. (посмотрев ваши прошлую трепню - в этом УЖЕ уверен)
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284612
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Програмёр, ок. Вариант рабочего кода, сделанный из первого примера (согласен, поторопился с примером.)

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
// Класс подготовки sql выражения и параметров к запросу -- исключительно для примеру.
// Показать что оно только оперирует со своей структурой объекта и больше ничего не делает:
class Select {
    protected $parts = array( 'from'=>array(), 'select'=>array(), 'where'=>array() /*, и другие запчасти выражения...*/ );
    protected $bindData = array();

    public function From($table, $alias)
    {
        $this->parts['from'][$alias] = $table;
    }
    public function Where($col, $data)
    {
        $this->parts['where'][$col] = '?';
        $this->bindData[$col] = $data;
    }
    // ... и другие методы сброки запчастей запроса и параметров к нему... не суть важно как.

    public function toString()
    {
        // формирует из массива строку запроса, тоже не вопрос.
    }
}

// вот предмет вопроса:
// класс определяющий статический, наследуемый метод для подготовки выражения запроса
// и метод объекта, который отдает данные вызывая статикой подготовку запроса
class Base
{
    protected $db = null;

    // собственно заглушка. Наверное можно сделать даже abstract, не пробовал.
    static public function getSql( Select $sql, array $params ) { return false; }

    // конструктор объекта, формирует подключение объекта к БД... способ не важен.
    function __construct( ) {
        $this->db = // ... здесь генерируется соединения с базой тем или иным способом
    }

    // метод объекта, отдает данные из БД, <<<<< похоже в нём и проблема: >>>>>
    public function getData(array $params)
    {
        $className = get_class($this);

        // получаем строку запроса тем способом, который определен в дочернем(!) классе, подсовывая ему новый объект выражения:
        // в PHP 5.3 можно вызывать напрямую через переменную - квалификатор класса. У меня 5.2.17 - приходится так:
        $funcName = $className . '::getSql';
        $sql = call_user_func($funcName, new Select, $params);

        // отдаем данные через объект подключения к БД дочернего объекта:
        return $this->db->query( $sql->toString(), $sql->bindData );
    }
}

// дочерний класс А - реализует свой способ доступа к данным (часть запроса):
// идея в том, что то что "умеет" делать объект этого класса - собрано тут
// , а не размазано по всему коду моделей прямыми или не очень запросами... см. далее "применение". 
class A extends Base {
    static function getSql( Select $sql, array $params) // return modified Select object!
    {
        $sql->From('table1', 'a');
        if( isset($params['col1']) ) { $sql->Where('col1', $params['col1']); }
        return $sql;
    }
}

// дочерний класс В -- имеет в подчинении объекты класса А и вызывает явно его статический метод для "досборки запроса"
// это и есть причина, почему метод сборки запроса - статический: он может вызываться напрямую у тех классов
// , которые "знают" что есть зависимые от них сущности... или от которых они зависят (reference map в ZF или где ещё)
// Поскольку не создается куча зависимых объектов "прочих классов", такой подход - значительно экононмнее и шустрее:
class B extends Base {
    static function getSql( Select $sql, array $params)
    {
        $subSelect = ( A::getSql(new Select, $params['A']) )->toString();
        $sql->From($subSelect, 'b');
        $sql->Where('col2', $params['B']['col2']);
        return $sql;
    }
}

// включил в общее описание примере и вызов КАк оно используется там, где валится:
class ModeModel {
    public static function getModeSelector(array $list = null, array $params = array(... набор условий по умолчанию...) )
    {
        if( !isset($list)) ) {
            $modeModel = new B();
            $params['B'] = array('col1'=>'this_const_string', 'limit'=>array('count'=>50, 'offset'=>0)); // $params['col2'] - как приходит, так и передается дальше.
            $list = $modeModel->getData($params);
        }
        $result = array();
        foreach( $list as $num => $item) {
             $result[] = .. преобразование по набору условий из второго параметра $params;
        }
        return $result;
    }
}

// Действие контроллера ZF, которое вызывает эту функцию
// (создается объект класса и вызывается его метод в диспетчере запросов ZF)
//, который сам вызывается из index.php, на который перенаправлены все урлы в .htaccess
//
class SomeController extends Zend_Controller_Action {

    // @params $_GET['id'], .. and other params from user request...
    public function someAction() {
       // ... валидация пришедших параметров урла запроса
       // ...
       $this->view->modeOptions = ModeModel::getModeSelector(
            array( 'A' => array(
                'col2' => (int)$_GET['id']
            ))
        );
    }
}



Это полный пример использования такого подхода. Достоинства и недостатки - тут обсуждать не намерен. Тут хочется понять проблему и её решить.

В частности, обращаю внимание на этот факт (вопроизводится 100%):

при любом изменении даты файла класса ModeModel.php -- апач начинает работать, произвольное время. Потом все одно - валится.

Как это может происходить?!?

P.S. очень большая просьба писать по делу: "не пишите мне какой фреймворк НАДО использовать, и я не пошлю вас туда, где он у меня УЖЕ лежит". :)
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284615
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109,

блин, все равно с параметрами в массивах накосячил... надо было в редакторе писать, а не тут править... :)

смысел - понятен, надеюсь.
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38284622
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109,

Дополню ещё по ситуации:
0. Рекурсий там нет. Есть примерно та вложенность, которая описана в примере... Есть и больше, но там "всё работает".

1. Скрипт запускается, отдает ответы, всё нормально... какое-то время.

2. Потом (непонятно когда) происходит выдача апачем ошибки "canary mismatch .. efree() heap overflow .." в которой указавается в том числе и строка действия контроллера, которая вызывает именно такую функцию.

3. Есть ещё более 50 классов, куча действий, работающих на этой же модели доступа к БД и гораздо сложнее: запросы по 70 строк по 80 символов - генерятся полностью через этот подход... однако работают нормально и устойчиво... и крайне шустро.

4. После того как выпала 502 ошибка, далее такие страницы (их много) все отдаются только с 502.

5. Достаточно перезаписать файл с этой функцией (ModeModel.php в примере, например добавить/убрать пробел в комментах)... апач начинает отдавать страницы верно... и даже БЕЗ перезагрузок (кеш?!? где?!?)... но опять произвольное время...

... цикл повторяется.
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38285014
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторМодератор: Скаря, пора бы объяснить уже поводы для веселья, растолковать "что не так" в высказываниях оппонентов.

это бесполезно. он все равно не понимает. ссылку на нормальный ORM ему давали в самом начале. потом выяснилось что ORM то у него уже есть.

код представляет собой какую то мешанину. я честно пытаюсь его понять уже второй день и у меня не выходит. потом выясняется что для вызова статических методов надо создавать экземпляр класса. человека в это тыкают два раза, он просто это не воспринимает.

по сабжу топика. думаю если переделать вызов статических методов в вызов динамических половина падений пройдет.
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38285055
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow,

для тех, кто в танке, ещё раз: для вызова статических методов экземпляр класса создавать НЕ надо... собственно не удивительно.

По теме: ещё утром внесли изменения. 6 часов - "полет нормальный". Если завтра не упадет, значит исправили.
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38285058
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109ScareCrow,

для тех, кто в танке, ещё раз: для вызова статических методов экземпляр класса создавать НЕ надо... собственно не удивительно.


а как же:
автор поскольку объект класса уже создан и метод объекта, вполне способен вызвать дочерний статический метод...
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38285222
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrow,

как-то так: 14386918
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38285424
Arhat109
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arhat109,

полёт всё ещё нормальный, тему похоже можно закрывать (ах как хочется верить! :).
...
Рейтинг: 0 / 0
PHP: Вызов static метода из метода объекта. Баг или фича?
    #38285811
apapacy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну хоть бы написали шо исправили прежде чем тему закрывать-то.
...
Рейтинг: 0 / 0
25 сообщений из 66, страница 2 из 3
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP: Вызов static метода из метода объекта. Баг или фича?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]