看到一个开源的项目中的一段代码,并没有对一个类进行实例化,只是在使用之前require_once了一次这个类文件,就直接调用了这个类中的一个方法,这在php中,难道是允许的吗?更奇怪的是,在直接调用的方法里,才有对这个的类的实例化。代码如下:调用的地方:
require_once INCLUDE_PATH . '/core/include/ApplicationController.php';
ApplicationController::init();ApplicationController类:
  function init()
    {
    
..................

        $controller =& ApplicationController::getInstance();
        
$controller->loadLang();

        $controller->parseRequest(); $controller->loadModule();

$controller->executeAction();
}刚学php不久,请各位大侠指教,先表示感谢。

解决方案 »

  1.   

    关键是这个类并不是静态类或者静态方法,请大家一定看清楚了源代码。这与单例模式也无关,可能我贴的代码误导大家了。我把全部代码贴出来,大家看看。index.php文件代码如下:require_once INCLUDE_PATH . '/core/include/ApplicationController.php'; @set_time_limit(0);
    @error_reporting(E_ALL);ApplicationController::init(); ApplicationController类文件如下:
        
        /**
         * Constructeur
         */
        function ApplicationController(){}
        
        
        /**
         * Singleton
         */
        function &getInstance()
        {
            static $instance;
            
            if (!isset($instance)){
                $c = __CLASS__;
                $instance = new $c;
            }
            return $instance;
        }function init() 
        { 
        
    ..................         $controller =& ApplicationController::getInstance(); 
            
    $controller->loadLang();         $controller->parseRequest(); $controller->loadModule(); $controller->executeAction(); 
    } 这个类也是静态类吗?
        
      

  2.   

    $controller =& ApplicationController::getInstance(); //调用ApplicationController类的getInstance方法,获得ApplicationController类的实例
            
    $controller->loadLang(); //使用ApplicationController类的实例
    在这里 ApplicationController::getInstance() 与普通函数没有本质的区别
      

  3.   

    看注释呀,
        /**
        * Singleton
        */ 
    是不是单例不是我说了算,这种方式,成熟一点的程序架构都喜欢用,比如joomla1.5
    还可以动态化单例,如果实例化带有参数,可以通过eval实现。
    你的代码是php4风格的,既然要单例,构造函数就不应该是public
    class application
    {
           //构造函数只开放给类内部
    private function __construct(){}
    //关键点在函数名前的&,表示返回引用,以及函数内部的static声明
        public static function &getInstance($name)
    {
    static $classArray = array();
    if(!$classArray[$name]){
    $classArray[$name] = new $name();
    }
    return $classArray[$name];
    }
    }
    class a{

    }
    class b{}
    /**
    $a与$a2同为一个实例化对象
    */
    $a = & application::getInstance('a');//要返回引用,调用时也要加上 &
    $a2 = & application::getInstance('a');//要返回引用,调用时也要加上 &
    $a2->v = 'i am a!';//给$a2对象属性赋值,会影响$a对象
    echo $a->v;
    /**
    $b与$b2同为一个实例化对象
    */
    $b = & application::getInstance('b');
    $b2 = & application::getInstance('b');
    $b2->v = 'i am b!';
    echo $b->v;
      

  4.   

    首先对各位的回复表示衷心的感谢。
    不知道大家有没有注意到,在index.php页面里,直接调用的是applicationcontroller的init方法,并不是它的getInstance方法,然后在init方法中才调用到它的getInstance方法。我知道这个类用到了单例模式,我的理解,按照正常是不是应该如下:先调用getInstance()方法获得该类的实例
    然后再调用它的其他方法记得在C#里一般都是这样,是不是可能因为PHP的require_once就不需要先调用getInstance了。我主要的疑问是觉得调用的顺序不对,觉得应该先是getInstance然后再调用其他的
      

  5.   

    init方法不是先调用了getInstance实例化了本类了吗,人家希望在实例化后马上执行一系列操作,就把实例化和一系列操作同时扔到init里咯,这也没什么不对,也不难理解吧?
      

  6.   

    谢谢foolbirdflyfirst的回复,可能是我表述的不清楚。
    这样好了,从新写一下那个ApplicationController类
    把init方法改成如下:
    init()
    {
        define("SITE_NAME", "ABCDEF");
        define("SITE_DB_HOST", "liztrack");
        define("SITE_DB_USERNAME", "liztrack");
        define("SITE_DB_PASSWORD", "liztrack");
    }如果变成这样,那么在index.php页面里还可以直接调用ApplicationController::init()方法吗?真的很感谢foolbirdflyfirst的耐心回复
      

  7.   

    谢谢wisword回复,现在的问题,不是用什么方法来解决这个问题。问题是不明白为什么在php里这样不实例化类,竟然就可以直接使用,现在要的是这里边的原因。再次表示感谢
      

  8.   

    可以调用ApplicationController::init(),但是做的是不同的事。
    你是不明白为什么方法可以这么调用?
    ApplicationController::init();
    虽然init未指定为类的静态外部可调用函数,但是这么写php还是会把init转换作为类ApplicationController的静态方法进行调用.
    1.类::类方法();//类调用类的方法。
    2.$对象->对象方法();//实例化对象调用实例化对象的方法。
    它们是不一样的。
      

  9.   

    噢,终于明白了,原来在php里是可以这样直接调用的。谢谢foolbirdflyfirst耐心解答。你说的这两种调用方法,有什么不同?为什么可以这么调用?我在php的文档里也没有查到这样的调用方法。