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

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

<?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 ()?

http://www.php.net/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 совпадает с именем класса, который вы хотите создать.