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 :: autoload в mvc [2]

 PHP.SU

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


 Страниц (3): « 1 [2] 3 »   

> Описание: autoload в mvc
GoDr
Отправлено: 30 Января, 2015 - 14:03:49
Post Id



Посетитель


Покинул форум
Сообщений всего: 446
Дата рег-ции: Янв. 2015  
Откуда: Тамбов


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




Ну т.е.
вместо
PHP:
скопировать код в буфер обмена
  1. self::$_lib_url =LibUrl::getInstance();

я буду вызывать
PHP:
скопировать код в буфер обмена
  1. self::$_lib_url = LIBRARIES\LibUrl::getInstance();


В итоге в LAutoloader->Connect передаётся не LibUrl, а LIBRARIES\LibUrl

И с учётом этого если сам файл-класс находится не по адресу
...\LIBRARIES\LibUrl....
то мне в любом случае придутся парсить имя переданного класса, так? Если так, то тогда чем мой код хуже? Не понял


-----
Система управления веб-содержимым Lotos CMS
 
 Top
esterio
Отправлено: 30 Января, 2015 - 14:21:11
Post Id



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


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


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




juramaj пишет:
Как избавится в маршрутизаторе на mvc от include, а вместо этого реализовать функцию autoload для загрузки классов. Вот мой маршрутизатор:

Autoload работает когда создаеться екземпляр класа который не подключен. Далее сами
 
 Top
juramaj
Отправлено: 30 Января, 2015 - 14:31:53
Post Id


Гость


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


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




esterio пишет:
juramaj пишет:
Как избавится в маршрутизаторе на mvc от include, а вместо этого реализовать функцию autoload для загрузки классов. Вот мой маршрутизатор:

Autoload работает когда создаеться екземпляр класа который не подключен. Далее сами

Мозг взрывается, не могу понять. У меня же в маршрутизаторе берутся переменные с адресной строки, не могу понять как мне их подгрузить(файлы в которых есть эти классы) не используя include. Может хоть намекнёте?
 
 Top
GoDr
Отправлено: 30 Января, 2015 - 14:57:15
Post Id



Посетитель


Покинул форум
Сообщений всего: 446
Дата рег-ции: Янв. 2015  
Откуда: Тамбов


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




суть автозагрузки в следующем

Допустим есть класс MyClass и в нём есть метод getValue.
И есть класс NoMyClass и в нём есть метод setValue.

Классы находятся в файлах myclass.php и nomyclass.php

Вопрос: как вызвать MyClass::getValue() и NoMyClass::setValue($str)?

1. без автозагрузки
PHP:
скопировать код в буфер обмена
  1. // Определяем корень сайта
  2. define('_PATH_ROOT', __DIR__);
  3.  
  4. // Подключаем класс MyClass
  5. require_once _LPATH_ROOT . '/class/myclass.php';
  6.  
  7. // Подключаем класс NoMyClass
  8. require_once _LPATH_ROOT . '/class/nomyclass.php';
  9.  
  10. // Вызываем
  11. $str = MyClass::getValue();
  12. NoMyClass::setValue($srt)


2. С автозагрузкой

имеем самый простой Класс автозагрузки
PHP:
скопировать код в буфер обмена
  1. class LAutoloader
  2. {
  3.     public static function Connect($class_name = '')
  4.     {
  5.         if (!class_exists($class_name)) {
  6.              require_once(_PATH_ROOT . '/class/' . $class_name . '.php');
  7.         }
  8.     }
  9. }


теперь как это работает
PHP:
скопировать код в буфер обмена
  1. // Определяем корень сайта
  2. define('_PATH_ROOT', __DIR__);
  3.  
  4. // Далее подключаем файл автозагрузки в котором и есть наш LAutoloader
  5. require_once _LPATH_ROOT . '/core/autoloader.php';
  6.  
  7. // Далее определяем сам обработчик, т.е. указываем какой класс и метод
  8. // будет обрабатывать вызов несуществующего класса
  9. spl_autoload_register(array('LAutoloader', 'Connect'));
  10.  
  11. // Вызываем
  12. $str = MyClass::getValue();
  13. NoMyClass::setValue($srt)
  14.  


Теперь что происходит при вызове:
- мы вызываем MyClass::getValue()
- но такого класса нет ещё и поэтому название класса (MyClass) автоматически передаётся

- метод получает переменную, а вот что дальше с ней делать уже решаешь сам

В данном примере мы получаем имя класса. И мы знаем что имя совпадает с названием файла. И мы знаем какой путь до файла. А значит мы просто подставляем недостающий адрес и подключаем файл

Ну где-то так если кратко Улыбка

(Отредактировано автором: 30 Января, 2015 - 15:01:47)



-----
Система управления веб-содержимым Lotos CMS
 
 Top
esterio
Отправлено: 30 Января, 2015 - 15:13:58
Post Id



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


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


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




GoDr
Извините но вы ошибаетесь
1. зачем проверять
GoDr пишет:
if (!class_exists($class_name)) {
require_once(_PATH_ROOT . '/class/' . $class_name . '.php');
}

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

juramaj
Чтобы не запутивать вас обьясню коротко.

Есть файл MyClass.php
в нем обьявлен класс MyClass

и есть файл test.php с кодом
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. // включаем вывод ошибок
  3. ini_set('display_errors', 1);
  4.  
  5. $myclass = new MyClass();
  6. var_dump($myclass); // null
  7.  


прописиваем в адресной строке http://localhost/test.php
в том виде который сейчас у нас получиться ошибка про то что класс MyClass не обьявлен
для этого дополним наш test.php чтобы он имел следующий вид
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. // включаем вывод ошибок
  4. ini_set('display_errors', 1);
  5.  
  6. function autoload($classname)
  7. {
  8.     include($classname.'.php');
  9. }
  10.  
  11.  
  12. $myclass = new MyClass();
  13. var_dump($myclass); // object MyClass
  14.  


как видно из примера все работает отлично. теперь попорядку.
При создании обьекта ПХП смотрт обьявлен ли такой класс или нет. Если не обьявлен то визовет функцию autoload. Визовет именно ее потому, что именно ее название мы пеердали в качестве аргумента в функцию spl_autoload_register.
В свою очередь первым аргументом при визове autoload будет имя класса который мы хотим создать (но который до сих пор не обьявлен). В даном случае переменная $classname будет равна MyClass. А далее мы подключаем ПХП файл который имеет такое же название как и класс

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

Примерно такая магия

(Отредактировано автором: 30 Января, 2015 - 15:41:31)

 
 Top
GoDr
Отправлено: 30 Января, 2015 - 15:21:44
Post Id



Посетитель


Покинул форум
Сообщений всего: 446
Дата рег-ции: Янв. 2015  
Откуда: Тамбов


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




esterio пишет:
1. зачем проверять
да знаю Радость а вдруг инопланетяне ....

esterio пишет:
2. пример с довома класамми и со статикой не самый удачный
Почему?


-----
Система управления веб-содержимым Lotos CMS
 
 Top
digi
Отправлено: 30 Января, 2015 - 15:34:51
Post Id


Посетитель


Покинул форум
Сообщений всего: 406
Дата рег-ции: Янв. 2012  


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




Если код пишется в соотвествии с PSR, то удобнее всего использовать автозагрузчик композера:

Создаётся файл composer.json

CODE (javascript):
скопировать код в буфер обмена
  1. {
  2.     "require": {
  3.         "php": ">=5.3.0",
  4.         "symfony/class-loader": "*"
  5.     },
  6.     "autoload": {
  7.         "psr-0": { "": "src/" }
  8.     }
  9. }


Затем выполняется команда:

CODE (htmlphp):
скопировать код в буфер обмена
  1. $ composer install
  2. Loading composer repositories with package information
  3. Installing dependencies (including require-dev)
  4.   - Installing symfony/class-loader (v2.6.3)
  5.     Downloading: 100%
  6.  
  7. Writing lock file
  8. Generating autoload files


Теперь в папке проекта будет находиться папка vendor, которая включает в себя собственно сам автозагрузчик autoload.php. Также создаём папку src в которой и будет весь код проекта в соответствии с PSR-0 без сторонних библиотек, которые будут лежать в vendor.

Использовать можно так:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. require_once 'vendor/autoload.php';
  3.  
  4. // my code


И самое интересное - это кеш автозагрузчика! ;) т.е. чтобы не было попыток находить файл, его имя и полный путь кешируется в APC, WinCache, XCache и т.д.

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. // /app/autoload.php
  3. if (version_compare(PHP_VERSION, '5.4', '>=') && gc_enabled()) {
  4.     // Disabling Zend Garbage Collection to prevent segfaults with PHP5.4+
  5.     // https://bugs.php.net/bug.php?id=53976
  6.     gc_disable();
  7. }
  8.  
  9. /**
  10.  * @var $loader \Composer\Autoload\ClassLoader
  11.  */
  12. $loader = require __DIR__.'/../vendor/autoload.php';
  13.  
  14. // Autodetect autoloader cacheing.
  15. if (function_exists('apc_store') and ini_get('apc.enabled')) {
  16.     $loader = new \Symfony\Component\ClassLoader\ApcClassLoader(md5(__FILE__), $loader);
  17.     $loader->register(true);
  18. } else if (function_exists('wincache_ucache_set')) {
  19.     $loader = new \Symfony\Component\ClassLoader\WinCacheClassLoader(md5(__FILE__), $loader);
  20.     $loader->register(true);
  21. } else if ((PHP_SAPI != 'cli' || (isset($_SERVER['DOCUMENT_ROOT']) && isset($_SERVER['REQUEST_URI'])))
  22.     and function_exists('xcache_set') and (int) ini_get('xcache.var_size') > 0
  23.     ) {
  24.     $loader = new \Symfony\Component\ClassLoader\XcacheClassLoader(md5(__FILE__), $loader);
  25.     $loader->register(true);
  26. }
  27.  
  28. return $loader;


Вот тогда работает весьма шустро всё Улыбка

PS: путь к autoload.php в require_once у вас может быть любой.

(Отредактировано автором: 30 Января, 2015 - 15:39:06)

 
 Top
DelphinPRO
Отправлено: 30 Января, 2015 - 16:27:47
Post Id



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


Покинул форум
Сообщений всего: 7187
Дата рег-ции: Февр. 2012  


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




digi пишет:
Если код пишется в соотвествии с PSR, то удобнее всего использовать автозагрузчик композера:

Вот вам ответ на все вопросы по автолоаду. Современно, красиво и идеологически правильно. Улыбка


-----
Чем больше узнаю, тем больше я не знаю.
 
 Top
juramaj
Отправлено: 30 Января, 2015 - 17:03:13
Post Id


Гость


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


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




[quote=esterio]GoDr
Извините но вы ошибаетесь
1. зачем проверять
[quote=GoDr] if (!class_exists($class_name)) {
require_once(_PATH_ROOT . '/class/' . $class_name . '.php');
}[/quote]
если автолоадер не будет вызван если клас обьявлен
2. пример с довома класамми и со статикой не самый удачный

juramaj
Чтобы не запутивать вас обьясню коротко.[quote]
Теорию то я понял, а вот как оно на практике реализуется именно с моим случаем маршрутизатор? Как избавится от тех include, а чтобы всё автоматически подгружалось не могу понять.
 
 Top
esterio
Отправлено: 30 Января, 2015 - 17:15:28
Post Id



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


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


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




смотрте если есть include то мы явно обьявляем класс, значит автозагрузчик не сработает, а если убрать что будет тогда думаю можно догадатся
 
 Top
juramaj
Отправлено: 30 Января, 2015 - 17:22:32
Post Id


Гость


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


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




esterio пишет:
смотрте если есть include то мы явно обьявляем класс, значит автозагрузчик не сработает, а если убрать что будет тогда думаю можно догадатся

Вы не можете помочь мне переписать маршрутизатор. Я новичок в mvc и мне бы хоть разок увидеть как это всё реализуется и всё. Вот код:
PHP:
скопировать код в буфер обмена
  1. class Route
  2. {
  3.     static function start()
  4.     {
  5.         $controller_name = 'Main';
  6.         $action_name = 'index';
  7.         $routes = explode('/', $_SERVER['REQUEST_URI']);
  8.         if ( !empty($routes[1])){      
  9.             $controller_name = $routes[1];
  10.         }
  11.         if ( !empty($routes[2])){
  12.             $action_name = $routes[2];
  13.         }
  14.         $model_name = 'Model'.$controller_name;
  15.         $controller_name = 'Controller'.$controller_name;
  16.         $action_name = 'action'.$action_name;
  17.         $model_file = strtolower($model_name).'.php';
  18.         $model_path = "application/models/".$model_file;
  19.         if(file_exists($model_path)){
  20.           //  spl_autoload_register(Route::loaderModel);
  21.           //  include "application/models/".$model_file;
  22.         }
  23.         $controller_file = strtolower($controller_name).'.php';
  24.         $controller_path = "application/controllers/".$controller_file;
  25.         if(file_exists($controller_path)){
  26.          //   include "application/controllers/".$controller_file;
  27.         } else {
  28.             Route::ErrorPage404();
  29.         }  
  30.        $controller = new $controller_name;
  31.         $action = $action_name;
  32.         if(method_exists($controller, $action)){
  33.             $controller->$action();
  34.         } else {
  35.             Route::ErrorPage404();
  36.         }
  37.     }
  38.     static function ErrorPage404()
  39.     {
  40.         echo "<img src='images/404.png' alt='404'>";
  41.     }
  42. }

(Добавление)
esterio пишет:
смотрте если есть include то мы явно обьявляем класс, значит автозагрузчик не сработает, а если убрать что будет тогда думаю можно догадатся

когда я убрал include то меня перебросило на 404
 
 Top
GoDr
Отправлено: 30 Января, 2015 - 17:30:45
Post Id



Посетитель


Покинул форум
Сообщений всего: 446
Дата рег-ции: Янв. 2015  
Откуда: Тамбов


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




digi пишет:
Если код пишется в соотвествии с PSR, то удобнее всего использовать автозагрузчик композера:
Где можно почитать про это в ракурсе "для чайников"? Никогда не делал такое и смутно представляю как использовать?


-----
Система управления веб-содержимым Lotos CMS
 
 Top
digi
Отправлено: 30 Января, 2015 - 17:35:33
Post Id


Посетитель


Покинул форум
Сообщений всего: 406
Дата рег-ции: Янв. 2012  


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




GoDr, начать можно вот отсюда Улыбка

CODE (text):
скопировать код в буфер обмена
  1. https://www.google.ru/search?q=composer


ну и разумеется

CODE (text):
скопировать код в буфер обмена
  1. https://www.google.ru/search?q=psr


ну и в целом

CODE (text):
скопировать код в буфер обмена
  1. https://www.google.ru/search?q=php+right+way

(Отредактировано автором: 30 Января, 2015 - 17:36:38)

 
 Top
GoDr
Отправлено: 30 Января, 2015 - 17:45:47
Post Id



Посетитель


Покинул форум
Сообщений всего: 446
Дата рег-ции: Янв. 2015  
Откуда: Тамбов


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





digi пишет:
https://www.google.ru/search?q=composer
digi+1 Даже не подумал о Гугле Хорошо А если по правде, то перед постом конечно же почитал, но понял процентов на 20 Не понял


-----
Система управления веб-содержимым Lotos CMS
 
 Top
digi
Отправлено: 30 Января, 2015 - 18:40:53
Post Id


Посетитель


Покинул форум
Сообщений всего: 406
Дата рег-ции: Янв. 2012  


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




GoDr, это нормально Улыбка) надо просто брать и пробовать, а в практике и понимание придёт.
 
 Top
Страниц (3): « 1 [2] 3 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


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



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

 
Powered by ExBB FM 1.0 RC1. InvisionExBB