Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: class_exists загружает класс

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: class_exists не просто проверяет, но загружает класс
MAXUS
Отправлено: 10 Августа, 2015 - 08:21:42
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Столкнулся с интересным нюансом при организации динамического кэша.

При использовании автозагрузки классов всем известная функция class_exists(), которая должна проверять, существует ли класс, не просто проверяет, но и загружает класс. Выявляется это и несколько вводит в заблуждение, если после вызова функции динамически изменить класс, т.е. переписать файл.

PHP:
скопировать код в буфер обмена
  1. function autoload($class_name){
  2.         require_once(__DIR__ . DIRECTORY_SEPARATOR . $class_name . '.php');
  3. }
  4.  
  5. if (version_compare(phpversion(), '5.3.0', '>=')) spl_autoload_register('autoload',true,false);
  6. else spl_autoload_register('autoload',true);
  7.  
  8. file_put_contents(
  9.         __DIR__ . DIRECTORY_SEPARATOR . 'some_class.php',
  10.         '<?
  11.         class some_class{
  12.                         public function __construct(){
  13.                                 echo 1;
  14.                         }
  15.                 }
  16.         ?>'
  17. );
  18. if( class_exists('some_class') ) echo 'Класс some_class существует, ';
  19. file_put_contents(
  20.         __DIR__ . DIRECTORY_SEPARATOR . 'some_class.php',
  21.         '<?
  22.         class some_class{
  23.                         public function __construct(){
  24.                                 echo 2;
  25.                         }
  26.                 }
  27.         ?>'
  28. );
  29. $some_class = new some_class();


Вместо ожидаемого (мнойУлыбка) 'Класс some_class существует, 2', на экран выводится 'Класс some_class существует, 1'...

В принципе, ничего удивительного тут нет и логика понятна. Class_exists() проверяет наличие класса, т.е. был ли он загружен, при этом при обращении к классу происходит его автозагрузка. Далее динамические изменения файла уже ни на что не влияют, т.к. файл в новом виде уже не подгружается и используется старый класс.

Просто делюсьУлыбка

(Отредактировано автором: 10 Августа, 2015 - 08:24:15)

 
 Top
DeepVarvar Супермодератор
Отправлено: 10 Августа, 2015 - 08:36:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




http://php.net/manual/ru/functio...class-exists.php

Цитата:
bool class_exists ( string $class_name [, bool $autoload = true ] )

Цитата:
Список параметров

class_name
Имя класса. Воспринимается без учета регистра.

autoload
Вызывать ли по умолчанию __autoload.
 
 Top
MAXUS
Отправлено: 10 Августа, 2015 - 08:46:50
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




DeepVarvar пишет:
http://php.net/manual/ru/functio...class-exists.php

Цитата:
bool class_exists ( string $class_name [, bool $autoload = true ] )

Цитата:
Список параметров

class_name
Имя класса. Воспринимается без учета регистра.

autoload
Вызывать ли по умолчанию __autoload.


Там фишка в том, что я при помощи class_exists по сути проверял наличие файла. У меня идет проверка есть ли файл и не устарел ли он. Но вместо file_exists я наивный хотел использовать более 'целевую' функцию class_exists, но оказалось, что был не прав.

В принципе, если бы не надо было проверять не устарел ли файл, то я бы воспользовался флагом autoload в class_exists, но у меня, если файл устарел, его надо поменять и только после этого он используется и, соответственно, загружается.
 
 Top
DeepVarvar Супермодератор
Отправлено: 10 Августа, 2015 - 08:50:16
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




MAXUS пишет:
есть ли файл и не устарел ли он

http://php.net/manual/ru/function.filemtime.php
 
 Top
MAXUS
Отправлено: 10 Августа, 2015 - 08:59:14
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




DeepVarvar пишет:
MAXUS пишет:
есть ли файл и не устарел ли он

http://php.net/manual/ru/function.filemtime.php


Да это-то понятноУлыбка
 
 Top
Мелкий Супермодератор
Отправлено: 10 Августа, 2015 - 10:51:13
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




MAXUS пишет:
if (version_compare(phpversion(), '5.3.0', '>='))

MAXUS пишет:
__DIR__

Вы уж определитесь: или реально писать и тестировать код на всякой фигне или же выкидывать ненужный код сразу, дабы не засорять.

MAXUS пишет:
при организации динамического кэша.

Стукните по башке архитектору томиком GoF (или ещё чем тематическим) и используйте адекватные задаче шаблоны проектирования.


-----
PostgreSQL DBA
 
 Top
MAXUS
Отправлено: 10 Августа, 2015 - 12:06:52
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Мелкий пишет:
MAXUS пишет:
if (version_compare(phpversion(), '5.3.0', '>='))

MAXUS пишет:
__DIR__

Вы уж определитесь: или реально писать и тестировать код на всякой фигне или же выкидывать ненужный код сразу, дабы не засорять.

MAXUS пишет:
при организации динамического кэша.

Стукните по башке архитектору томиком GoF (или ещё чем тематическим) и используйте адекватные задаче шаблоны проектирования.


Ну, то что __DIR__ в 5.2 не работает это понятно. Просто кусок кода выдрал из того, что под 5.2 тоже должно работать.

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

Опишу задачу.

Есть файл вида (HTML со вставками кода шаблонизатора). Он парсится и создается файл с классом с определенным именем в папке с кэшем (назовем это так).
При запуске страницы сначала проверяется скомпилированный кэш-файл с классом. Если его нет или он протух (определяется по нескольким параметрам, не только по времени файла), то файл вида перекомпилируется.
После этого используется скомпилированный класс.

Прям любопытно стало, это стандартная смс была, которая автоматически постится, типа "я занят" насчет шаблонов или что-то конкретное имеется в виду и есть какой-то шаблон, который решает задачу?

Дополнение

ЗЫ Мне кажется, что количество невинно убиенных томиком GoF в мире (или только в России) растет неоправданно быстрыми темпамиУлыбка

(Отредактировано автором: 10 Августа, 2015 - 12:42:03)

 
 Top
Мелкий Супермодератор
Отправлено: 10 Августа, 2015 - 12:46:53
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Это ещё и шаблонизатор? Ну вот зачем вам там динамические классы?

С приложением должен общаться порождающий паттерн, приложение не должно задумываться, из кеша это чтение было сделано или более дорогим способом каким-то. Для шаблонов уместна фабрика, которая будет порождать объект с требуемыми характеристиками. Дальше (обычно при построении объекта самим объектом, чтобы фабрика о кешах не знала тоже) можно пнуть кэширующий прокси, который отдаст данные из кеша или, в случае промаха, пнёт тяжеловесный метод построения шаблона и, попутно, сохранения результата построения в кэш.


-----
PostgreSQL DBA
 
 Top
MAXUS
Отправлено: 10 Августа, 2015 - 12:57:56
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Мелкий пишет:
Это ещё и шаблонизатор? Ну вот зачем вам там динамические классы?


Очень хороший и удобный подход. Используется, например, в Twig.

Мелкий пишет:
С приложением должен общаться порождающий паттерн, приложение не должно задумываться, из кеша это чтение было сделано или более дорогим способом каким-то. Для шаблонов уместна фабрика, которая будет порождать объект с требуемыми характеристиками. Дальше (обычно при построении объекта самим объектом, чтобы фабрика о кешах не знала тоже) можно пнуть кэширующий прокси, который отдаст данные из кеша или, в случае промаха, пнёт тяжеловесный метод построения шаблона и, попутно, сохранения результата построения в кэш.


Да так все и происходит примерно. Я только не пойму как из примера, который я запостил, можно было сделать какие-то выводы об архитектуре приложения, которые бы позволяли рукоприкладствовать бумажной версией книги о шаблонах проектирования? Улыбка
 
 Top
Мелкий Супермодератор
Отправлено: 10 Августа, 2015 - 13:11:58
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




MAXUS пишет:
Да так все и происходит примерно.

Ну и зачем вам тогда тут классы? Кеш пишется и читается в одном месте. Зачем вообще автозагрузчику знать о кеше?
Зачем строковые данные превращать в исполняемый код?

MAXUS пишет:
Я только не пойму как из примера, который я запостил, можно было сделать какие-то выводы об архитектуре приложения

По генерации класса. Класса!


-----
PostgreSQL DBA
 
 Top
MAXUS
Отправлено: 10 Августа, 2015 - 13:19:05
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Мелкий пишет:
MAXUS пишет:
Да так все и происходит примерно.

Ну и зачем вам тогда тут классы? Зачем строковые данные превращать в исполняемый код?


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

Класс удобно использовать, потому что есть автозагрузка. И вообще, класс удобно использоватьУлыбка
 
 Top
Мелкий Супермодератор
Отправлено: 10 Августа, 2015 - 13:34:31
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Да, про исполняемый код я загнул, исполняемым ему быть надо. А вот классом - нет.
Контрпримеры: laravel/blade, nette (будь он неладен, но для примера подойдёт).


-----
PostgreSQL DBA
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB