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
Форумы портала PHP.SU :: Версия для печати :: autoload в mvc [2]
Форумы портала PHP.SU » » Объектно-ориентированное программирование » autoload в mvc

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

16. GoDr - 30 Января, 2015 - 14:03:49 - перейти к сообщению
Ну т.е.
вместо
PHP:
скопировать код в буфер обмена
  1. self::$_lib_url =LibUrl::getInstance();

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


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

И с учётом этого если сам файл-класс находится не по адресу
...\LIBRARIES\LibUrl....
то мне в любом случае придутся парсить имя переданного класса, так? Если так, то тогда чем мой код хуже? Не понял
17. esterio - 30 Января, 2015 - 14:21:11 - перейти к сообщению
juramaj пишет:
Как избавится в маршрутизаторе на mvc от include, а вместо этого реализовать функцию autoload для загрузки классов. Вот мой маршрутизатор:

Autoload работает когда создаеться екземпляр класа который не подключен. Далее сами
18. juramaj - 30 Января, 2015 - 14:31:53 - перейти к сообщению
esterio пишет:
juramaj пишет:
Как избавится в маршрутизаторе на mvc от include, а вместо этого реализовать функцию autoload для загрузки классов. Вот мой маршрутизатор:

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

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

Допустим есть класс 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) автоматически передаётся
PHP:
скопировать код в буфер обмена
  1. LAutoloader->Connect('MyClass')

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

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

Ну где-то так если кратко Улыбка
20. esterio - 30 Января, 2015 - 15:13:58 - перейти к сообщению
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. А далее мы подключаем ПХП файл который имеет такое же название как и класс
PHP:
скопировать код в буфер обмена
  1. include($classname.'.php');

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

Примерно такая магия
21. GoDr - 30 Января, 2015 - 15:21:44 - перейти к сообщению
esterio пишет:
1. зачем проверять
да знаю Радость а вдруг инопланетяне ....

esterio пишет:
2. пример с довома класамми и со статикой не самый удачный
Почему?
22. digi - 30 Января, 2015 - 15:34:51 - перейти к сообщению
Если код пишется в соотвествии с 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 у вас может быть любой.
23. DelphinPRO - 30 Января, 2015 - 16:27:47 - перейти к сообщению
digi пишет:
Если код пишется в соотвествии с PSR, то удобнее всего использовать автозагрузчик композера:

Вот вам ответ на все вопросы по автолоаду. Современно, красиво и идеологически правильно. Улыбка
24. juramaj - 30 Января, 2015 - 17:03:13 - перейти к сообщению
[quote=esterio]GoDr
Извините но вы ошибаетесь
1. зачем проверять
[quote=GoDr] if (!class_exists($class_name)) {
require_once(_PATH_ROOT . '/class/' . $class_name . '.php');
}[/quote]
если автолоадер не будет вызван если клас обьявлен
2. пример с довома класамми и со статикой не самый удачный

juramaj
Чтобы не запутивать вас обьясню коротко.[quote]
Теорию то я понял, а вот как оно на практике реализуется именно с моим случаем маршрутизатор? Как избавится от тех include, а чтобы всё автоматически подгружалось не могу понять.
25. esterio - 30 Января, 2015 - 17:15:28 - перейти к сообщению
смотрте если есть include то мы явно обьявляем класс, значит автозагрузчик не сработает, а если убрать что будет тогда думаю можно догадатся
26. juramaj - 30 Января, 2015 - 17:22:32 - перейти к сообщению
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
27. GoDr - 30 Января, 2015 - 17:30:45 - перейти к сообщению
digi пишет:
Если код пишется в соотвествии с PSR, то удобнее всего использовать автозагрузчик композера:
Где можно почитать про это в ракурсе "для чайников"? Никогда не делал такое и смутно представляю как использовать?
28. digi - 30 Января, 2015 - 17:35:33 - перейти к сообщению
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
29. GoDr - 30 Января, 2015 - 17:45:47 - перейти к сообщению

digi пишет:
https://www.google.ru/search?q=composer
digi+1 Даже не подумал о Гугле Хорошо А если по правде, то перед постом конечно же почитал, но понял процентов на 20 Не понял
30. digi - 30 Января, 2015 - 18:40:53 - перейти к сообщению
GoDr, это нормально Улыбка) надо просто брать и пробовать, а в практике и понимание придёт.

 

Powered by ExBB FM 1.0 RC1