Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> call to a member function XX on a non-object in... Ошибка вызова функции в подключеном файл 
:(
    Опции темы
SergV
Дата 21.8.2014, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 4.8.2006
Где: Германия

Репутация: нет
Всего: 1



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

Ситуация следующая, имеется файл индексный, в котором в самом начале подключаю файл с настройками, а в нём подключаю файл с классом, и этот клас инициализирую в файле настроек.

Дальше всё просто, в индексном файле вызываю функцию подключение макета - $tpl->loadLayout('xxx'), и в подключенном макете вызываю функцию подключения блока(в) - $tpl->loadBlock('xxx'). Так вот, в индексном файле всё норм, вызываются функции без проблем, а в подключенном файле макета функция выдаёт ошибку, но при статическом вызове TPL::$tpl->loadBlock('xxx'), всё работает нормально.

Пытался разобраться сам, но чего то не пойму, почему не передаётся объект в другой файл, который подключил... 
Я уже давно с пыхом не работал, а с классами и вообще подавно, и нагуглить чёт не вышло, английского не знаю, а на русском всё не по теме. Мож кто подскажет где проблема, чего не так делаю?

ПС. Пых 5.4, локальный сервер OpenServer. Класс стандартный, с "парой" публичных функций, думаю смысла нет приводить, так как там не чего особо нет, кроме пары строк в каждой, да и всё работает в общем то, кроме файла макета...
PM   Вверх
baldina
Дата 21.8.2014, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



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

Добавлено через 1 минуту и 26 секунд
Цитата(SergV @  21.8.2014,  16:54 Найти цитируемый пост)
в индексном файле вызываю функцию подключение макета - $tpl->loadLayout('xxx')

а $tpl где родится? а в подключенном файле макета она доступна?

PM MAIL   Вверх
SergV
Дата 21.8.2014, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 4.8.2006
Где: Германия

Репутация: нет
Всего: 1



Имеется основной файл index.php шаблона...
Код

<?php defined('_JEXEC') or die;  
include_once (file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'incl' . DIRECTORY_SEPARATOR . 'config.php')) 
    ? __DIR__ .DIRECTORY_SEPARATOR .'incl' . DIRECTORY_SEPARATOR . 'config.php' 
    : trigger_error('Import not found object: ', E_USER_ERROR);
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->language; ?>" lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>" >
...
</head>
<body>
...
<?php $tpl->loadLayout('default'); ?>
...
</body>

В нём инклюдится файл настроек, в котором константы и т.д., и инклюд класса.
Код

<?php defined('_JEXEC') or die('Restricted access');

class TPL
{
...
public function loadLayout($layout = false, $view = false) {
...  Обработка входящих данных    
include JPATH_THEMES.DS.TPL.DS.'layouts'.DS.$layout.'.php';
}

public function loadBlock($block = false, $layout = false) {
... Обработка входящих данных        
include JPATH_THEMES.DS.TPL.DS.'layouts'.DS.'blocks'.DS.$block.'.php';
}

Там же в config.php и инициализация класса - $tpl = new TPL;

Вызов идёт из index.php - $tpl->loadLayout('layout-name')
В "layout-name" хтмл вёрстка и вызов блока - $tpl->loadBlock('block-name'), где оствшаяся хтмл вёрстка. Вот тут и выходит ошибка вызова функции, но если вызывать как TPL::$tpl->loadBlock('xxx'), то всё норм.

Суть в том, что до переноса в класс, в config.php были просто две функции, и они вызывались без проблем, а в классе такая вот байда вышла... :(

Это сообщение отредактировал(а) SergV - 21.8.2014, 17:26
PM   Вверх
baldina
Дата 21.8.2014, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



Цитата(SergV @  21.8.2014,  17:23 Найти цитируемый пост)
public function loadLayout($layout = false, $view = false) {
...  Обработка входящих данных    
include JPATH_THEMES.DS.TPL.DS.'layouts'.DS.$layout.'.php';
}

$tpl недоступен отсюда. его надо передать в параметрах или, если он глобальный, 

Код

public function loadLayout($layout = false, $view = false) {
global $tpl;
include JPATH_THEMES.DS.TPL.DS.'layouts'.DS.$layout.'.php';
}


Добавлено через 38 секунд
однако он будет доступен и так, только не через $tpl а через $this

Добавлено через 10 минут и 33 секунды
т.е.
Код

$this->loadBlock('xxx');

PM MAIL   Вверх
SergV
Дата 21.8.2014, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 4.8.2006
Где: Германия

Репутация: нет
Всего: 1



Спасибо, чёт ступил, не попробовал через $this вызывать, думал не прокатит, тепрь работает.   smile 

А попутный вопрос, можно как то так через $tpl делать, но не использовать global $tpl, так как вроде по старой памяти, глобалки не советуют из за проблем с защищённостью или чего там ещё?

ПС. Интересно вообще, как функция в $this попала, если я класс инитиализировал как $tpl..., и не где не переопределял, и клас не наследуется не от какого другого.  smile  smile 

ПС2. Приколы, $this работает только для вызова из файла блоков в макете, а в индексном файле выдаёт туже ошибку.  Мда..., хочется вызывать одинаково, а то там одно, тут другое.

Это сообщение отредактировал(а) SergV - 21.8.2014, 18:08
PM   Вверх
baldina
Дата 21.8.2014, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



SergV
Цитата(SergV @  21.8.2014,  18:02 Найти цитируемый пост)
можно как то так через $tpl делать, но не использовать global $tpl

передать в качестве параметра.
но... не надо через $tpl, логика следующая:
контроллер создает $tpl - экземпляр TPL и работает с ним. $tpl - шаблон с исполняемым кодом, то есть view.
код в partial temlates, подключаемых через loadLayout() и loadBlock() - суть часть кода view, поэтому ему логично обращаться к объекту шаблона (типа TPL), а значит view, как к себе, через $this

Добавлено через 2 минуты и 22 секунды
Цитата(SergV @  21.8.2014,  18:02 Найти цитируемый пост)
$this работает только для вызова из файла блоков в макете, а в индексном файле выдаёт туже ошибку

ну естественно. блоки становятся частью кода функции-члена, а индексный файл - внешняя создающая и вызывающая среда.
индексный файл - controller, блоки - часть view. view целиком представлен в индексном файле как $tpl
PM MAIL   Вверх
ksnk
Дата 22.8.2014, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Если я правильно понял, TPL - классический синглтон класс. Нужно и работать с ним как с синглтоном.

Код

class TPL{
    private static $instance;  // экземпляра объекта
    private function __construct(){ /* ... @return Singleton */ }  // Защищаем от создания через new Singleton
    private function __clone()    { /* ... @return Singleton */ }  // Защищаем от создания через клонирование
    private function __wakeup()   { /* ... @return Singleton */ }  // Защищаем от создания через unserialize
    public static function getTpl() {    // Возвращает единственный экземпляр класса. @return Singleton
        if ( empty(self::$instance) ) {
            self::$instance = new self();
        }
        return self::$instance;
    }
 // то что было раньше  
 }
 


в нужных местах писать $tpl=TPL::getTpl() или TPL::getTpl()->do_something();


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Aliance
Дата 22.8.2014, 07:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 14
Всего: 137



ksnk, лучше наверное такой синглтон пометить как final, либо заменить self на static ;)
PM MAIL WWW ICQ Skype   Вверх
ksnk
Дата 22.8.2014, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Aliance, Если разработчики php будут и дальше толкать язык в сторону Java - то нет, на static заменять не стоит  smile final - да, для дополнительного лоска - можно добавить. 

Текст стырен откуда-то, вероятно с википедии, так что мопед не мой я на нем только катаюсь...   smile 


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
SergV
Дата 22.8.2014, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 4.8.2006
Где: Германия

Репутация: нет
Всего: 1



baldina, сказать честно, понял через слово, совсем уже забыл что к чему в пхп, занимаясь 3д дизайном. smile
Так или иначе, нашёл шаблон один, где подобная иеархия с подключением, правдо там всё идет через плагин(класс в плагине сидит), но в шаблоне везде вызов на подключение идёт как я писал... Попробую там подсмотреть что и как делается, и вытянуть что надо из плагина в шаблон.

ksnk, спасибо за пример, но я с классами давным давно начинал работать, но так и не освоил толком, да и уже забыл что к чему.

В общем придётся пока делать обходным путём, вызывая блоки через $this, и постепенно разбираться с найденным шаблоном и его плагином... Не вышло по быстрому сделать нормально, думал тряхну стариной, раз раз и на матрац, а $тут-> smile  smile 

ПС. Глючит меня с утра, в найденом шаблоне точно так же, вызов макета через объявление класса и т.д., а подключение блоков через $this...

В общем вопрос снимается, всем спасибо за ответы.


Это сообщение отредактировал(а) SergV - 22.8.2014, 11:32
PM   Вверх
baldina
Дата 22.8.2014, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 26
Всего: 101



Цитата(ksnk @  22.8.2014,  07:32 Найти цитируемый пост)
TPL - классический синглтон класс

синглтон - потенциально проблемное место для расширения. поэтому в отсутствие достаточных доводов TPL лучше синглотоном не считать
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1552 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.