簡體   English   中英

如何在變量類上調用靜態方法?

[英]How can I call a static method on a variable class?

我正在嘗試創建一種從給定變量加載和實例化類的函數。 像這樣的東西:

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

在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()函數之外調用那些不是“new”的東西。

雖然,正如其他人早先指出的那樣,__ autoload()可能對您有用。

您可以使用call_user_func()

$class = call_user_func(array($class, 'getInstance'));

第一個參數是一個callback類型,在這種情況下包含類名和方法名。

為什么不使用__autoload()函數?

http://www.php.net/autoload

那么你只需要在需要時實例化對象。

我認為,后期靜態綁定對你有用。 在每個類的構造中做:

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

但是你必須在名為ClassName.php的路徑中有一個php文件,其中ClassName與要實例化的類的名稱相同。

看起來你正在與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;
        }
    }

?>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM