2009-03-13 15 views
29

मैं किसी प्रकार का फ़ंक्शन बनाने की कोशिश कर रहा हूं जो किसी दिए गए चर से कक्षा को लोड और तत्काल करता है। कुछ इस तरह:मैं एक चरणीय वर्ग पर एक स्थिर विधि कैसे कॉल कर सकता हूं?

<?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 
    $session = session::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]; 
    } 

    } 

?> 

बात यह है कि अभी जिस तरह से एक वर्ग में फ़ंक्शन का उपयोग करने के लिए है यह है लेकिन अब मैं इसे एक फ़ंक्शन में बनाना चाहता हूं ताकि मुझे कभी भी कोड की उस पंक्ति का उपयोग न करना पड़े। मैं बस लोड क्लास ('सत्र') कहता हूं; और मैं $ सत्र-> blablablafunction() का उपयोग कर सकता हूं;

उत्तर

36

आप call_user_func() उपयोग कर सकते हैं:

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

पहला तर्क classname और इस मामले में विधि नाम से युक्त एक callback प्रकार है।

2

क्यों __autoload() फ़ंक्शन का उपयोग नहीं करते?

http://www.php.net/autoload

तो तुम सिर्फ वस्तु जब जरूरत का दृष्टांत।

0

ऐसा लगता है कि आप PHP के वर्तमान कार्यान्वयन स्थिर बाध्यकारी से लड़ रहे हैं, यही कारण है कि आप getCallingClass के साथ हुप्स के माध्यम से कूद रहे हैं। मैं आपको अनुभव से बता सकता हूं, आपको शायद एक स्थिर विधि के माध्यम से अभिभावक वर्ग में तत्कालता डालने की कोशिश करनी चाहिए। यह आपको अंत में और अधिक समस्याएं पैदा करेगा। PHP 5.3 "late static binding" लागू करेगा और आपकी समस्या का समाधान करना चाहिए, लेकिन यह स्पष्ट रूप से अब सहायता नहीं करता है।

आप ठोस सिंगलटन कार्यान्वयन के साथ संयुक्त कोडिशा द्वारा उल्लिखित ऑटोलोड लोड कार्यक्षमता का उपयोग कर शायद बेहतर हो सकते हैं। मुझे यकीन नहीं है कि आपका लक्ष्य वाक्य रचनात्मक चीनी है या नहीं, लेकिन ऐसा लगता है कि आप कुछ पात्रों को बचाने की कोशिश करने के स्पष्ट होने के लिए लंबे समय तक बेहतर प्रदर्शन करेंगे।

0

मेरे सिर के ऊपर बंद, परीक्षण की जरूरत है, सत्यापन आदि:

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

एक चर वर्ग के नाम पर स्थिर कार्यों कॉलिंग पीएचपी 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; 
    } 

}

या

बस इसे से एक वस्तु बनाने के बिना वर्ग लोड। फिर loadclass() फ़ंक्शन के बाहर से, उन लोगों पर "getInstance()" को सिंगलेट्स और "नया" पर कॉल करें।

हालांकि, जैसा कि अन्य ने पहले बताया है, एक __autoload() शायद आपके लिए अच्छा काम करेगा।

0

देर से स्थिर बाइंडिंग आपके लिए काम करेंगे। प्रत्येक वर्ग की संरचना में कार्य करें:

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

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

फिर ... यहाँ एक autoloader मैं बनाया है। देखें कि यह आपकी दुविधा को हल करता है या नहीं।

// 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 के नाम के समान है करना होगा कक्षा जिसे आप तत्काल करना चाहते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे