PHP scope between two classes
I have a few files like below:
index.php:
require_once("foo.php");
require_once("bar.php");
foo.php:
class foo {
function1() {
}
}
bar.php:
class bar {
?????
}
My question is, is there any way of accessing function1 fro开发者_JS百科m the foo class in the bar class, without having to include the foo.php file in the bar.php file, as it has already been loaded in index.php?
Thanks in advance
When including a file, in PHP, you are not including anything into the current file, but into the current execution
Once a file has been included, it's content is known by the PHP interpreter -- and will remain known until the end of the execution of the current script.
It's a bit like copy-pasting : with your current index.php
file, it's like if you had taken the code from foo.php
and bar.php
and copy-pasted into index.php
.
So, yes, once foo.php
has been loaded once, you can access what's defined by it from bar.php
-- even if those two are included by index.php
.
(What you means by access is a bit vague, though : you'll have to declare some methods as static, or instanciate the foo
class, ... But all that will be possible from inside the body on a method declared in bar
)
As a sidenote : you should be careful with your file inclusions : if you include twice a file that declares a class, for example, you'll get a fatal error, because it's forbidden to define two classes with the same name.
Remember the copy-pasting idea I wrote about earlier ? Includind a file twice, even from two distinct files, is like copy-pasting the same code twice...
To avoid that problem, we often use include_once
which, as its name indicates, makes sure that a given file can only be included only once.
If foo.php
has already been loaded, then the real question to ask yourself is, "Am I accessing function1()
in a static or instance manner?"
If function1()
is a static function (which in your example, is not):
class bar{
function function2(){
return foo::function1();
}
}
Otherwise, you will have to instantiate an instance of foo
, making it a local- or class-scope variable, e.g.
class bar{
/*
* @var foo
*/
private $foo;
function __construct(){
$this->foo = new foo();
}
function function2(){
return $this->foo->function1();
}
}
Read this too: http://php.net/manual/en/language.oop5.static.php
By the way, like what Pascal MARTIN has explained, you do not need to do another include()
, but usually for a large application, you will prefer auto-class-loading.
You should try to move away from including files manually, and instead work towards a solution where you can use autoloading.
Autoloading will allow you to lazy load, or only load the files that you need in each request - rather than making a spider web of included files.
You can do this either with __autoload or spl_autoload, read more on the subject here: http://php.net/manual/en/language.oop5.autoload.php
Small example of autoload below:
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
Using autoloading php can automatically try to load files when a class is not found, in this example there is no reason to include the class files for MyClass1 or MyClass2, php falls back to the __autoload function if it cannot find definitions for them.
Using this will mean you dont have to include either foo or bar in your examples, nor include them in index.php
You could do it statically, though there are limitations and this is an atrocious practice, since that function isn't actually static.
foo::function1();
The better approach would be to have the class bar take foo as a parameter. Depending on the uses, this could be done in the constructor or the particular method.
精彩评论