我想知道是否有人可以帮助我理解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变量。
Notice: Undefined variable: r1 in C:\wamp\www\options.ex\public_html\app\options.php on line 77
如果我要将$ r变量传递给函数,我会想出没有问题,但是因为它们是全局声明的,我想知道为什么没有这样做就看不到它们,因为它们的范围可能是全局的?
感谢。
编辑 - 完整代码。
<?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 *变量不再在此处再次使用,因此可以方便地在会话中使用。
答案 0 :(得分:1)
那不是OOP - 在OOP中你要声明一个类,使r1,r2和r3成为它的属性,然后它们将在类的每个方法中可用。查看有关课程here的小教程。
使用全局变量是一个坏主意。
修改
这是一个示例代码,如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();
答案 1 :(得分:0)
reference to the global个变量。但是,globals are bad。
如果变量定义发生在“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移到使用变量的行之前,因为这与全局变量共享一个大问题:变量看似神奇地存在,并没有指示如何或在何处,制作只需阅读函数就很难理解函数(以及代码的其余部分)。这是coupling的一种形式。
通过包含文件来执行代码有时可能是一个有用的技巧,但它也经常会导致问题(正如这个问题所示)。通常,包含文件应该只定义事物。对于OO方法,请执行所包含文件正在执行的任何任务,并确定代码尝试实现的整体任务。然后,将每个任务分配给具有(单个)职责的类,以实现每个整体工作。在这种情况下,特定任务是将请求分解为路由,并且整个作业将请求分派给控制器。然后应该有一个调度程序类,它使用一种解析路由的方法将请求分派给适当的控制器。该方法(可能是私有的或受保护的,并从构造函数中调用)可以将路由存储在实例变量中以实现时间效率。
class RouteDispatcher {
protected $route;
function __construct() {
$this->_parseRoute();
...
}
function dispatch() {
...
}
protected function _parseRoute() {
$this->route = explode('/', $_SERVER['REQUEST_URI']);
}
...
}
入口点(首先调用以处理每个请求的脚本)将实例化RequestDispatcher
,设置任何适当的属性或调用任何必要的方法,然后调用RequestDispatcher::dispatch
,这将创建适当的控制器并将控制权交给其请求处理程序。
在一般情况下,良好的设计可能比这更棘手,因为您在创建具有single responsibility的类时作为设计者的目标是减少更改它们的需要。如果一个类只有一个责任,那么只有当该职责的要求发生变化时才需要更改该类。
答案 2 :(得分:0)
为了在函数内部使用全局变量,您必须通过以下方式执行此操作
$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
}
答案 3 :(得分:0)
在函数内添加此功能。
全球$ r1,$ r2,$ r3;
这告诉函数使用全局范围内的变量。
答案 4 :(得分:0)
$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'];
}
}
或在声明变量global
的函数内部function bar() {
global $baz;
echo $baz
}
答案 5 :(得分:0)
如果在任何类或函数定义之外定义了$ r1,$ r2和$ r3,则可以使用global关键字来访问它们,或者直接从$ GLOBALS数组中调用它们。 e.x:
function edit($id){
global $r1, $r2, $r3; //Rest of the function below this
或
$_SESSION['path'] = $GLOBALS['r1'].'/' //... etc.