2009-03-13 51 views
29

Tôi đang cố gắng thực hiện một số loại hàm tải và khởi tạo một lớp từ một biến nhất định. Một cái gì đó như thế này:Làm thế nào tôi có thể gọi một phương thức tĩnh trên một lớp biến?

<?php 
function loadClass($class) { 
    $sClassPath = SYSPATH."/classes/{$class}.php"; 
    if (file_exists($sClassPath)) { 
    require_once($sClassPath); 
    $class = $class::getInstance(); 
    } 
} 
?> 

Nếu tôi sử dụng nó như thế này:

<?php 
    loadClass('session'); 
?> 

Nó nên bao gồm và nhanh chóng lớp phiên.

BTW: chức năng getInstance tĩnh đến từ mã này:

<?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]; 
    } 

    } 

?> 

Cái này là ngay bây giờ các cách để sử dụng các chức năng trong một lớp học là thế này:

<?php 
    $session = session::getInstance(); 
?> 

Nhưng bây giờ tôi muốn xây dựng nó thành một hàm để tôi không bao giờ phải sử dụng dòng mã đó nữa. Tôi chỉ nói loadClass ('phiên'); và tôi có thể sử dụng $ session-> blablablafunction();

Trả lời

36

Bạn có thể sử dụng call_user_func():

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

Đối số đầu tiên là một loại callback chứa classname và tên phương pháp trong trường hợp này.

0

Dường như bạn đang chống lại việc thực thi tĩnh hiện tại của PHP, đó là lý do tại sao bạn nhảy qua hoops bằng getCallingClass. Tôi có thể cho bạn biết từ kinh nghiệm, có lẽ bạn nên từ bỏ cố gắng đặt instantiation trong một lớp cha thông qua một phương thức tĩnh. Nó sẽ gây ra nhiều vấn đề hơn cho bạn. PHP 5.3 sẽ thực hiện "late static binding" và nên giải quyết vấn đề của bạn, nhưng điều đó rõ ràng không giúp được gì.

Có lẽ bạn nên sử dụng chức năng tự động tải được đề cập bởi kodisha kết hợp với triển khai Singleton vững chắc. Tôi không chắc liệu mục tiêu của bạn có phải là cú pháp hay không, nhưng nó nghĩ bạn sẽ làm tốt hơn trong thời gian dài để tránh xa việc cố gắng tiết kiệm một vài nhân vật.

0

Off đỉnh đầu của tôi, cần kiểm tra, xác nhận vv:

<?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; 
     } 
    } 

?> 
36

Gọi chức năng tĩnh trên một tên lớp biến là dường như có sẵn trong PHP 5.3:

Foo::aStaticMethod(); 
$classname = 'Foo'; 
$classname::aStaticMethod(); // As of PHP 5.3.0 

http://php.net/manual/en/language.oop5.static.php

Chắc chắn có thể sử dụng nó ngay bây giờ.

Cho đến lúc đó bạn không thể thực sự cho rằng mọi lớp bạn đang tải đều được thiết kế để trở thành một singleton. Miễn là bạn đang sử dụng < 5.3 bạn sẽ phải chỉ tải các lớp và nhanh chóng thông qua các nhà xây dựng:

function loadClass($class) { 
    $sClassPath = SYSPATH."/classes/{$class}.php"; 
    if (file_exists($sClassPath)) { 
    require_once($sClassPath); 
    $class = new $class; 
    } 

}

HOẶC

Chỉ cần tải các lớp mà không cần tạo một đối tượng từ nó. Sau đó, gọi ":: getInstance()" trên các ngôn ngữ có nghĩa là các singletons và "new" trên những cái không có, từ bên ngoài hàm loadClass().

Mặc dù, như những người khác đã chỉ ra trước đó, một __autoload() có thể sẽ hoạt động tốt cho bạn.

0

Kết buộc tĩnh muộn sẽ làm việc cho bạn tôi nghĩ. Trong cấu trúc của mỗi lớp, hãy làm:

class ClassName 
{ 
    public static $instances = array(); 

    public function __construct() 
    { 
     self::$instances[] = $this; 
    } 
} 

Sau đó ... Đây là bộ nạp tự động mà tôi đã tạo. Xem liệu điều này có giải quyết được tình huống khó xử của bạn không.

// 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; 
} 

Sau đó, tất cả các bạn phải làm là

$var = new ClassName(); 

nhưng bạn phải có một file php trong đường dẫn với tên ClassName.php nơi ClassName là giống như tên của lớp bạn muốn khởi tạo.

Các vấn đề liên quan