我希望能够通过类方法要求页面。问题是,当我通过普通的require语句要求页面时,所有变量都可以在所需页面上访问,但如果我使用另一个类来要求该页面,则不再可以访问变量。
我有两个页面,index.php和other.php。
的index.php:
class Myclass {
public function test(){
$test='hello World';
$other=new other;
$other->other_page('other.php'); //if I change this line to require 'other.php' variables are accessible.
}
}
class other {
public function other_page($page){
require $page;
}
}
$class=new Myclass;
$class->test();
other.php
<?php
echo $test;
index.php给出了未定义的索引错误。但如果我改变了:
$other->other_page('other.php');
到
require 'other.php';
一切正常。我可以通过将它们传递给
来使这些变量可用other::other_page()
在这两种情况下,一切都是一样的。那么为什么类的行为不同,除了将变量传递给
之外,还有其他方法可以使变量可访问other::other_page()
答案 0 :(得分:2)
如有疑问,请始终参考docs
在大多数情况下,所有PHP变量只有一个范围。这个单一范围跨越包含和所需文件......但是,在用户定义的函数中引入了本地函数范围。函数内使用的任何变量默认都限制在本地函数范围内。
当包含文件时,它包含的代码将继承发生包含的行的变量范围。从那时起,调用文件中该行可用的任何变量都将在被调用文件中可用。但是,包含文件中定义的所有函数和类都具有全局范围。
问题是您的脚本other.php
继承了other_page()
方法的范围。在此方法内部,没有定义局部变量$test
。这就是你的错误所在的地方。现在,为什么MyClass
es test()
方法中的直接要求有效,这应该是合乎逻辑的。包含的文件继承了方法的范围,并且在其范围内确实存在$test
变量。
这是一般问题。我建议你重新考虑你的设计。
显式地将范围传递给您想要包含的脚本,而不是随机依赖某个范围<?php
// Controller.php
class Controller {
public function test()
{
$test = 'Hello World';
// You would probably want to pass that via Dependency-Injection and
// not as a hardcoded dependecny
$retriever = new PageRetriever;
// Only the contents of the second argument are passed
// to the getPage() method
echo $retriever->getPage('page.php', ['test' => $test]);
}
}
// PageRetriever.php
class PageRetriever {
public function getPage( $page, $args = [] )
{
$contents = null;
// Extract the contents of the $args array into
// the methods local scope
extract($args);
// Initiate output buffering, so that the contents
// of the script is not immediately displayed
ob_start();
require $page;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
}
这只是一个简单的实现,用来演示我在说什么。在这里你有一个干净的分离范围。您知道只有PageRetriever
中已明确传递的变量才可用。
答案 1 :(得分:0)
我将给你一个简单的例子,你可以理解访问机制
first.php
<?php
class first {
private $name;
function __construct() {
$this->name="name";
}
function changeName(){
$this->name="newName";
}
function getName()
{
return $this->name;
}
}
?>
second.php
<?php
include 'first.php';
$firstObject=new first;
echo $firstObject->getName().'<br>';
$firstObject->changeName();
echo $firstObject->getName();
?>
在您使用require 'other.php'
的情况下,该内容包含在Myclass
班级test()
功能中。在该位置$test
已定义。
但是当您使用$other->other_page('other.php');
时,该内容将包含在other
类的other_page($page)
功能中。在该位置$test
未定义。