PHP在两个类之间的作用域

PHP在两个类之间的作用域,php,class,scope,Php,Class,Scope,我有以下几个文件: index.php: require_once("foo.php"); require_once("bar.php"); foo.php: class foo { function1() { } } bar.php: class bar { ????? } 我的问题是,有没有办法从bar类中的foo类访问function1,而不必在bar.php文件中包含foo.php文件,因为它已经加载到index.php中了 提前感谢在PHP中包含文件时

我有以下几个文件:

index.php:

require_once("foo.php");
require_once("bar.php");
foo.php:

class foo {

   function1() {

   }

}
bar.php:

class bar {

   ?????

}
我的问题是,有没有办法从bar类中的foo类访问function1,而不必在bar.php文件中包含foo.php文件,因为它已经加载到index.php中了


提前感谢

在PHP中包含文件时,您不会将任何内容包含到当前文件中,而是包含到当前执行中

一旦包含了一个文件,PHP解释器就会知道它的内容——并且在当前脚本的执行结束之前都会知道它的内容

这有点像复制粘贴:使用当前的
index.php
文件,就像从
foo.php
bar.php
中获取代码,然后复制粘贴到
index.php
中一样


因此,是的,一旦
foo.php
加载一次,您就可以从
bar.php
访问它定义的内容——即使
index.php
中包含了这两个

(您所说的访问有点模糊:您必须将一些方法声明为静态的,或者实例化
foo
类,……但是所有这些都可以从
栏中声明的方法的主体内部实现。)


作为旁注:您应该小心文件包含:例如,如果您包含两次声明类的文件,您将得到一个致命错误,因为禁止使用相同的名称定义两个类

还记得我之前写的复制粘贴的想法吗?包含一个文件两次,即使是从两个不同的文件,就像复制粘贴相同的代码两次


为了避免这个问题,我们经常使用它,正如它的名字所表明的那样,确保一个给定的文件只能包含一次。

在PHP中,当包含一个文件时,您没有将任何内容包含到当前文件中,而是包含到当前执行中

一旦包含了一个文件,PHP解释器就会知道它的内容——并且在当前脚本的执行结束之前都会知道它的内容

这有点像复制粘贴:使用当前的
index.php
文件,就像从
foo.php
bar.php
中获取代码,然后复制粘贴到
index.php
中一样


因此,是的,一旦
foo.php
加载一次,您就可以从
bar.php
访问它定义的内容——即使
index.php
中包含了这两个

(您所说的访问有点模糊:您必须将一些方法声明为静态的,或者实例化
foo
类,……但是所有这些都可以从
栏中声明的方法的主体内部实现。)


作为旁注:您应该小心文件包含:例如,如果您包含两次声明类的文件,您将得到一个致命错误,因为禁止使用相同的名称定义两个类

还记得我之前写的复制粘贴的想法吗?包含一个文件两次,即使是从两个不同的文件,就像复制粘贴相同的代码两次


为了避免这个问题,我们经常使用它,正如它的名字所示,确保给定的文件只能包含一次。

如果
foo.php
已经被加载,那么真正要问自己的问题是,“我是以静态还是实例的方式访问
function1()
?”

如果
function1()
是静态函数(在您的示例中不是):

否则,您将必须实例化
foo
的实例,使其成为本地或类范围变量,例如

class bar{

  /*
   * @var foo
   */
  private $foo;

  function __construct(){
    $this->foo = new foo();
  }

  function function2(){
    return $this->foo->function1();
  }

}
也请阅读以下内容:


顺便说一句,正如Pascal MARTIN所解释的,您不需要再做一次
include()
,但通常对于大型应用程序,您会更喜欢。

如果
foo.php
已经加载,那么真正要问自己的问题是,“我是以静态还是实例的方式访问
function1()
?”

如果
function1()
是静态函数(在您的示例中不是):

否则,您将必须实例化
foo
的实例,使其成为本地或类范围变量,例如

class bar{

  /*
   * @var foo
   */
  private $foo;

  function __construct(){
    $this->foo = new foo();
  }

  function function2(){
    return $this->foo->function1();
  }

}
也请阅读以下内容:


顺便说一句,正如Pascal MARTIN所解释的,您不需要再执行另一个
include()
,但通常对于大型应用程序,您更喜欢静态执行。

您可以静态执行,尽管存在局限性,这是一种糟糕的做法,因为该函数实际上不是静态的

foo::function1();

更好的方法是让类栏将foo作为参数。根据用途的不同,这可以在构造函数或特定方法中完成。

您可以静态完成,尽管有一些限制,这是一种非常糟糕的做法,因为该函数实际上不是静态的

foo::function1();

更好的方法是让类栏将foo作为参数。根据使用情况,这可以在构造函数或特定方法中完成。

您应该尝试从手动包含文件转移到可以使用自动加载的解决方案

自动加载将允许您延迟加载,或者只加载每个请求中需要的文件,而不是创建包含文件的蜘蛛网

您可以使用_autoload或spl_autoload执行此操作,请阅读有关此主题的更多信息:

下面是自动加载的小示例:

function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 
使用自动加载php可以在找不到类时自动尝试加载文件,在本例中,没有理由包含MyClass1或MyClass2的类文件,如果无法找到它们的定义,php将返回_autoload函数


使用此选项意味着您不必在示例中包含foo或bar,也不必在index中包含它们。php

您应该尝试放弃手动包含文件,而是朝着可以使用自动加载的解决方案努力。