[英]PHP OOP: Can a variable be seen in a function without passing it as a param?
我想知道是否有人可以帮助我了解OO PHP的这一特定方面,因为它现在使我陷入了困境。
我已经在文件顶部指定了一个var,就像这样
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
然后,我试图在上面的代码下方编写的函数中使用$ r1等。
function edit($id)
{
$_SESSION['path'] = $r1 . "/" . $r2 . "/" . $r3;
require 'app/controller/edit.php';
new Controller($id);
}
$ r1,$ r2,$ r3 var出于某种原因在此函数内看不到。
Notice: Undefined variable: r1 in C:\wamp\www\options.ex\public_html\app\options.php on line 77
如果我将$ r vars传递给函数,我会认为不会有问题,但是由于它们是全局声明的,所以我想知道为什么不这样做就看不见它们,因为它们的范围可能是全局的?
谢谢。
编辑-完整代码。
<?php
require_once 'load.php';
// Clean and prepare query string
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Trim outer exmpty parameters caused by leading/trailing slash
if($route[count($route)-1]=='') unset($route[count($route)-1]);
if($route[0]=='') unset($route[0]);
$route = array_values($route);
// If any parameters are undefined, set them to ''
if(!isset($route[0])) { $route[0]=''; $route[1]=''; $route[2]=''; }
elseif(!isset($route[1])) { $route[1]=''; $route[2]=''; }
elseif(!isset($route[2])) { $route[2]=''; }
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
// Choose route, else default to dash
if($r1=='dashboard' && $r2=='' && $r3=='') dashboard();
elseif($r1=='staff' && $r2=='add' && $r3=='') add_staff();
elseif($r1=='staff' && $r2=='edit' && $r3!='') edit_staff($r3);
else header("location: http://local.options.ex/dashboard");
// Dashboard: Main entry point after login.
function dashboard()
{
require 'app/controller/dashboard/dashboard.php';
new Controller();
}
// Staff related interfaces ----------------------------------------------------
function add_staff()
{
require 'app/controller/staff/add_staff.php';
new Controller();
}
// ----------------------------------------
function edit_staff($staff_id)
{
$_SESSION['path'] = $r1 . "/" . $r2 . "/" . $r3;
require 'app/controller/staff/edit_staff.php';
new Controller($staff_id);
}
// ----------------------------------------
只是为了清理起见,这里不再使用$ r *变量,因此可以方便地在会话中使用存储。
那不是OOP-在OOP中,您将声明一个类,将r1,r2和r3设置为其属性,然后它们将在该类的每个方法中可用。 在这里查看有关类的一些教程。
使用全局变量是一个坏主意。
编辑
这是一个示例代码,如Sohnee所问:
Class Route {
var $r1;
var $r2;
var $r3;
function __construct($url)
{
$route = explode('/', $url);
// Shorthand
$this->r1=$route[0]; $this->r2=$route[1]; $this->r3=$route[2];
}
function test()
{
$path = $this->r1 . "/" . $this->r2 . "/" . $this->r3;
echo $path;
}
}
$a = new Route('http://stackoverflow.com/questions/');
$a->test();
如果将全局变量声明为全局变量(这会创建对global的本地引用 ),则可以在函数内访问全局变量。 但是, 全局变量是不好的 。
如果变量定义发生在“ app / controller / edit.php”中,那么问题就出在警告告诉您:尚未定义变量。 您只能在一行上使用它们,但是直到下一行才包含定义它们的文件,因此尚未定义它们。 就像函数是一样的:
function edit($id) {
$_SESSION['path'] = $r1 . "/" . $r2 . "/" . $r3;
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
...
}
我建议不要采用明显的修正方法:将require移到使用变量的行之前,因为这与全局变量存在一个大问题:变量似乎魔术般地存在,而没有指示如何或在何处进行,使其更难只需阅读函数即可了解该函数(以及代码的其余部分)。 这是耦合的一种形式。
通过包含文件来执行代码有时可能是一个有用的技巧,但它通常还会导致问题(如该问题所示)。 通常,包含文件应仅定义事物。 对于OO方法,请执行包含的文件正在执行的所有任务,并找出代码总体上要尝试完成的工作。 然后,将每个任务分配给负责完成每个总体工作的(单个)职责的班级。 在这种情况下,特定的任务是将请求分解为一条路由,而整个任务是将请求分派给控制器。 然后应该有一个调度程序类,该类通过解析路由的方法将请求调度到适当的控制器。 该方法(可以是私有的,也可以是受保护的,并可以从构造方法调用的方法)可以将路由存储在实例变量中,以节省时间。
class RouteDispatcher {
protected $route;
function __construct() {
$this->_parseRoute();
...
}
function dispatch() {
...
}
protected function _parseRoute() {
$this->route = explode('/', $_SERVER['REQUEST_URI']);
}
...
}
入口点(首先被调用来处理每个请求的脚本)将实例化RequestDispatcher
,设置任何适当的属性或调用任何必要的方法,然后调用RequestDispatcher::dispatch
,这将创建适当的控制器并将控制权RequestDispatcher::dispatch
给其请求处理程序。
在一般情况下,一个好的设计可能比这更棘手,因为作为设计师,创建具有单一职责的类的目标是减少对它们进行更改的需求。 如果班级只有一个职责,则只有在该班级的要求发生变化时才需要更改班级。
为了在函数内使用全局变量,您必须通过以下方式进行操作
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
// ...
function edit($id)
{
global $r1, $r2, $r3; // after this the variables are available in function scope
}
另一种选择是使用全局数组$ GLOBALS。 使用此数组,可以从任何如下范围访问全局变量:
if ($GLOBALS["r1"] == "some value")
{
// do something
}
将其添加到函数内部。
全局$ r1,$ r2,$ r3;
这告诉函数使用全局作用域中的变量。
全局变量可以在使用$GLOBALS
的方法中看到
$GLOBALS — References all variables available in global scope
http://php.net/manual/en/reserved.variables.globals.php
<?php
$baz = 'foo';
clas Bar {
public function __construct() {
echo $GLOBALS['baz'];
}
}
或在函数内声明全局变量
function bar() {
global $baz;
echo $baz
}
如果$ r1,$ r2和$ r3在任何类或函数定义之外定义,则可以使用global关键字来访问它们,或直接从$ GLOBALS数组中调用它们。 例如:
function edit($id){
global $r1, $r2, $r3; //Rest of the function below this
要么
$_SESSION['path'] = $GLOBALS['r1'].'/' //... etc.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.