Intereting Posts
Php mysqi bind_param Число переменных не соответствует количеству параметров в подготовленном операторе error_log в том же каталоге, что и включенные файлы? многомерный массив в случайном порядке Электронная почта phpMailer не отправляет gmail smtp как динамически установить конструктор библиотеки codeigniter Замена формы HTML с сообщением об успешности после отправки, форма отправляет почту с использованием отдельного php-файла PHP – перенастроить массив по определенному индексу адрес электронной почты div в php PHP не может загружать динамическую библиотеку «php_pdo_oci.dll» Ошибка Ajax – «разрешение отклонено» Доступ к SkyDrive с использованием PHP и OAuth Laravel 5 и WordPress 4.1.1 на одном сервере Предупреждение: session_start (): не удается отправить cookie сеанса – уже отправленные заголовки (вывод запущен в Заменить текст в скобках так называемой переменной в PHP Ошибка каждый второй раз, когда я делаю XMLHttpRequest в php-файл, используя dotnet

Автозагрузчик для функций

На прошлой неделе я узнал, что классы могут быть включены в ваш проект, написав функцию __autoload() . Затем я узнал, что использование автозагрузчика – это не только техника, но и шаблон.

Теперь я использую автозагрузчик в своем проекте, и я нашел его очень полезным. Мне было интересно, можно ли делать то же самое с функциями. Было бы очень полезно забыть о включении правого PHP-файла с функциями внутри него.

Итак, можно ли создать функцию автозагрузчика?

Для функций нет функции автозагрузчика. У вас есть четыре реалистичных решения:

  1. Оберните все функции в классы пространства имен (соответствующий контекст). Итак, скажем, у вас есть функция, называемая string_get_letters . Вы можете добавить это в класс StringFunctions как статическую функцию. Поэтому вместо вызова string_get_letters() вы вызываете StringFunctions::get_letters() . Затем вы __autoload эти классы с __autoload .

  2. Предварительно загрузите все функции. Поскольку вы используете классы, у вас не должно быть таких функций, поэтому просто загружайте их.

  3. Загружайте функции перед их использованием. В каждом файле require_once файлы функций, которые будут использоваться в этом файле.

  4. Не используйте функции в первую очередь. Если вы разрабатываете OOP-код (который, как вам кажется, в любом случае), он вообще не нуждается в каких-либо функциях. Все, для чего вам понадобится функция (или несколько), вы могли бы создать способ OO и избежать необходимости в функциях.

Лично я бы предложил 1, 2 или 4 в зависимости от вашей конкретной потребности и качества и размера вашей кодовой базы …

Если вы используете Composer в своем проекте, вы можете добавить директиву файлов в раздел автозагрузки.

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

Пример, взятый из Assetic :

 "autoload": { "psr-0": { "Assetic": "src/" }, "files": [ "src/functions.php" ] } 

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

Самое близкое, что у вас есть, – метод магии __call() , который является своего рода __autoload() для методов, а не для функций. Это может быть достаточно для ваших нужд; если вы можете позволить себе позвонить классу и потребовать каждую отдельную функцию отдельно. С PHP 5.3.0 у вас также есть __callStatic() .

Пример использования __callStatic() :

 class Test { public function __callStatic($m, $args) { if (function_exists($m) !== true) { if (is_file('./path/to/functions/' . $m . '.php') !== true) { return false; } require('./path/to/functions/' . $m . '.php'); } return call_user_func_array($m, $args); } } Test::functionToLoad(1, 2, 3); 

Это вызовет functionToLoad() определенную в ./path/to/functions/functionToLoad.php.

Ну, как обычно, для этого есть расширение PECL:

  • автомат PECL

(через: http://phk.tekwire.net/joomla/support/doc/automap.htm )

Он должен выполнять функции автозагрузки, а также классы. Однако это не работает с текущим интерпретатором PHP.

(Альтернативный вариант btw, генерирует функции-заглушки, которые загружают и запускают копии с именами.)

Что, как говорится. Автозагрузка не всегда считается хорошей практикой. Это приводит к чрезмерно раздробленным иерархиям классов и объекту счастья. И настоящая причина, по которой PHP имеет автозагрузку, заключается в том, что системы управления включением и зависимостями являются несовместимыми.

 namespace MyNamespace; class Fn { private function __construct() {} private function __wakeup() {} private function __clone() {} public static function __callStatic($fn, $args) { if (!function_exists($fn)) { $fn = "YOUR_FUNCTIONS_NAMESPACE\\$fn"; require str_replace('\\', '/', $fn) . '.php'; } return call_user_func_array($fn, $args); } } 

И используя пространства имен, мы можем сделать: Fn::myFunc() и spl_autoload_register() . Я использовал этот код с примерами по адресу: https://goo.gl/8dMIMj

Вот еще один довольно сложный пример, основанный на предложениях в этом обсуждении. Код можно также увидеть здесь: lib / btr.php

 <?php /** * A class that is used to autoload library functions. * * If the function btr::some_function_name() is called, this class * will convert it into a call to the function * 'BTranslator\some_function_name()'. If such a function is not * declared then it will try to load these files (in this order): * - fn/some_function_name.php * - fn/some_function.php * - fn/some.php * - fn/some/function_name.php * - fn/some/function.php * - fn/some/function/name.php * The first file that is found will be loaded (with require_once()). * * For the big functions it makes more sense to declare each one of them in a * separate file, and for the small functions it makes more sense to declare * several of them in the same file (which is named as the common prefix of * these files). If there is a big number of functions, it can be more * suitable to organize them in subdirectories. * * See: http://stackoverflow.com/questions/4737199/autoloader-for-functions */ class btr { /** * Make it TRUE to output debug info on '/tmp/btr.log'. */ const DEBUG = FALSE; /** * The namespace of the functions. */ const NS = 'BTranslator'; /** * Relative directory where the functions are located. */ const FN = 'fn'; private function __construct() {} private function __wakeup() {} private function __clone() {} /** * Return the full name (with namespace) of the function to be called. */ protected static function function_name($function) { return self::NS . '\\' . $function; } /** * Return the full path of the file to be loaded (with require_once). */ protected static function file($fname) { return dirname(__FILE__) . '/' . self::FN . '/' . $fname . '.php'; } /** * If a function does not exist, try to load it from the proper file. */ public static function __callStatic($function, $args) { $btr_function = self::function_name($function); if (!function_exists($btr_function)) { // Try to load the file that contains the function. if (!self::load_search_dirs($function) or !function_exists($btr_function)) { $dir = dirname(self::file($fname)); $dir = str_replace(DRUPAL_ROOT, '', $dir); throw new Exception("Function $btr_function could not be found on $dir"); } } return call_user_func_array($btr_function, $args); } /** * Try to load files from subdirectories * (by replacing '_' with '/' in the function name). */ protected static function load_search_dirs($fname) { do { self::debug($fname); if (file_exists(self::file($fname))) { require_once(self::file($fname)); return TRUE; } if (self::load_search_files($fname)) { return TRUE; } $fname1 = $fname; $fname = preg_replace('#_#', '/', $fname, 1); } while ($fname != $fname1); return FALSE; } /** * Try to load files from different file names * (by removing the part after the last undescore in the functin name). */ protected static function load_search_files($fname) { $fname1 = $fname; $fname = preg_replace('/_[^_]*$/', '', $fname); while ($fname != $fname1) { self::debug($fname); if (file_exists(self::file($fname))) { require_once(self::file($fname)); return TRUE; } $fname1 = $fname; $fname = preg_replace('/_[^_]*$/', '', $fname); } return FALSE; } /** * Debug the order in which the files are tried to be loaded. */ public static function debug($fname) { if (!self::DEBUG) { return; } $file = self::file($fname); $file = str_replace(DRUPAL_ROOT, '', $file); self::log($file, 'Autoload'); } /** * Output the given parameter to a log file (useful for debugging). */ public static function log($var, $comment ='') { $file = '/tmp/btr.log'; $content = "\n==> $comment: " . print_r($var, true); file_put_contents($file, $content, FILE_APPEND); } } 

Хотя вы не можете выполнять автонагрузку функций и констант, вы можете использовать что-то вроде jesseschalken / autoload-generator, который будет автоматически определять, какие файлы содержат вещи, которые невозможно автозагружать, и загружать их с нетерпением.

Включите весь файл функций в один файл, а затем включите его

// Файл 1
db_fct.php

// Файл 2
util_fct.php

// В файле functions.php включены все другие файлы

 <?php require_once 'db_fct.php'; require_once 'util_fct.php'; ?> 

Включите функции.php, когда вам нужны функции.

new Functions \ Debug () с автозагрузкой загрузит функции в корневое пространство имен.

 Функции имен
 {

     класс Debug
     {
     }
 }
 Пространство имен
 {

     if (! function_exists ('printr')) {

         / **
          *
          * @param mixed $ expression
          * /
         функция printr ()
         {
             foreach (func_get_args () как $ v) {
                 if (is_scalar ($ v)) {
                     echo $ v.  "\ П";
                 } else {
                     print_r ($ v);
                 }
             }
             Выход();
         }
     }
 }

попробуй это

 if ($handle = opendir('functions')) { while (false !== ($entry = readdir($handle))) { if (strpos($entry, '.php') !== false) { include("functions/$entry"); } } closedir($handle); } в if ($handle = opendir('functions')) { while (false !== ($entry = readdir($handle))) { if (strpos($entry, '.php') !== false) { include("functions/$entry"); } } closedir($handle); }