Я пытаюсь сделать какую-то функцию, которая загружает и создает экземпляр класса из заданной переменной. Что-то вроде этого:
<?php function loadClass($class) { $sClassPath = SYSPATH."/classes/{$class}.php"; if (file_exists($sClassPath)) { require_once($sClassPath); $class = $class::getInstance(); } } ?>
Если я использую его так:
<?php loadClass('session'); ?>
Он должен включать и создавать экземпляр класса сеанса.
BTW: статическая функция getInstance поступает из этого кода:
<?php function getCallingClass() { $backtrace = debug_backtrace(); $method = $backtrace[1]['function']; $file = file($backtrace[1]['file']); $line = $file[($backtrace[1]['line'] - 1)]; $class = trim(preg_replace("/^.+?([A-Za-z0-9_]*)::{$method}\(.*$/s", "\\1\\2", $line)); if(! class_exists($class)) { return false; } return $class; } class Core { protected static $instances = array(); public static function getInstance() { $class = getCallingClass(); if (!isset(self::$instances[$class])) { self::$instances[$class] = new $class(); } return self::$instances[$class]; } } ?>
Дело в том, что прямо сейчас способ использования функций в классе заключается в следующем:
<?php $session = session::getInstance(); ?>
Но теперь я хочу построить это в функцию, чтобы мне больше не пришлось использовать эту строку кода. Я просто говорю loadClass ('session'); и я могу использовать $ session-> blablablafunction ();
Вы можете использовать call_user_func()
:
$class = call_user_func(array($class, 'getInstance'));
Первый аргумент – это тип callback
содержащий имя класса и имя метода в этом случае.
Вызов статических функций в имени класса переменных, по-видимому, доступен в PHP 5.3:
Foo::aStaticMethod(); $classname = 'Foo'; $classname::aStaticMethod(); // As of PHP 5.3.0
http://php.net/manual/en/language.oop5.static.php
Мог бы определенно использовать это прямо сейчас.
До тех пор вы не можете предположить, что каждый класс, который вы загружаете, предназначен для одиночной игры. Пока вы используете <5.3, вам нужно просто загрузить класс и создать экземпляр через конструктор:
function loadClass($class) { $sClassPath = SYSPATH."/classes/{$class}.php"; if (file_exists($sClassPath)) { require_once($sClassPath); $class = new $class; }
}
ИЛИ
Просто загрузите класс, не создавая из него объект. Затем вызовите «:: getInstance ()» для тех, которые предназначены для синглонов, и «новые» для тех, которые не являются, вне функции loadClass ().
Хотя, как указывали другие ранее, __autoload (), вероятно, будет хорошо работать для вас.
Почему бы не использовать функцию __autoload ()?
то вы просто создаете объект при необходимости.
Похоже, вы ведете старую привязку к текущей реализации PHP, поэтому вы прыгаете через обручи с помощью getCallingClass. Я могу сказать вам по опыту, вы, вероятно, должны отказаться от попытки создания экземпляра в родительском классе с помощью статического метода. В конце концов это вызовет больше проблем. PHP 5.3 будет реализовывать «позднюю статическую привязку» и должен решить вашу проблему, но это, очевидно, сейчас не помогает.
Вероятно, вам лучше использовать функциональность автозагрузки, упомянутую kodisha, в сочетании с прочной реализацией Singleton. Я не уверен, что ваша цель – синтаксический сахар или нет, но он думает, что в конечном итоге вы добьетесь большего успеха, чтобы избежать попыток сохранить несколько символов.
В верхней части моей головы требуется тестирование, проверка и т. Д.
<?php function loadClass($className) { if (is_object($GLOBALS[$className])) return; $sClassPath = SYSPATH."/classes/{$className}.php"; if (file_exists($sClassPath)) { require_once($sClassPath); $reflect = new ReflectionClass($className); $classObj = $reflect->newInstanceArgs(); $GLOBALS[$className] = $classObj; } } ?>
Думаю, для вас будут работать старые статические привязки. В конструкции каждого класса выполните:
class ClassName { public static $instances = array(); public function __construct() { self::$instances[] = $this; } }
Затем … Вот автозагрузчик, который я создал. Посмотрите, решит ли это вашу дилемму.
// Shorten constants for convenience define ('DS', DIRECTORY_SEPARATOR); define ('PS', PATH_SEPARATOR); $template = "default"; // Define an application path constants define ('APP_ROOT', realpath('.').DS); define ('VIEW', APP_ROOT . 'Views' . DS); define ('MODEL', APP_ROOT . 'Models' . DS); define ('CONTROLLER', APP_ROOT . 'Controllers' . DS); define ('TEMPLATE', VIEW."templates".DS.$template.DS); define ('CONTENT', VIEW."content".DS); define ('HELPERS', MODEL."helpers".DS); // Check if application is in development stage and set error reporting and // logging accordingly error_reporting(E_ALL); if (defined('DEVELOPMENT')) { ini_set('display_errors', 1); } else { ini_set('display_errors', 0); ini_set('log_errors', 'On'); ini_set('error_log', APP_ROOT.'error.log'); } $paths = array(APP_ROOT, VIEW, MODEL, CONTROLLER, TEMPLATE, CONTENT, HELPERS); // Set the include path from Config Object set_include_path(implode(PS, $paths)); // Autoloader function __autoload($class) { require_once $class.'.php'; return; }
Тогда все, что вам нужно сделать, это
$var = new ClassName();
но вы должны иметь php-файл в пути с именем ClassName.php, где ClassName совпадает с именем класса, который вы хотите создать.