required_once() 中的变量未定义但可与 require() 一起使用,为啥?
Posted
技术标签:
【中文标题】required_once() 中的变量未定义但可与 require() 一起使用,为啥?【英文标题】:variable from required_once() not defined but works with require(), why?required_once() 中的变量未定义但可与 require() 一起使用,为什么? 【发布时间】:2017-03-25 12:46:18 【问题描述】:我对编程很陌生,必须制作一个与 php7 兼容的网站。
我不想更改更多我需要的代码,所以我决定将旧的已弃用(不再工作)mysql_
更改为新的mysqli_
db-connection。
到目前为止,一切都运行良好,但在一些脚本中,我遇到了 db-connection-script 的 require_once 问题,它包含在脚本的顶部并且运行良好,但在同一脚本中的“函数”中包含db-connection-file 和它的变量不可用,即使我再次“include_once”它。
但如果我只是“包含()”它,它会再次起作用。我的问题是,为什么? 据我了解,在没有“include_once”的情况下多次包含一个文件可能会导致问题,所以我真的需要帮助来理解这个问题。
index.php:
<?php
require_once('../../Connections/db.php');
mysqli_select_db($dbcon, $dbname);
$query = "SELECT x, y FROM dbtable WHERE z";
效果很好,但在同一个文件中:
function pruefe_datum($datum)
if (!function_exists("GetSQLValueString"))
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
require_once('../../Connections/db.php');
$theValue = mysqli_escape_string($dbcon, $theValue);
抛出:
注意:未定义变量:dbcon 和警告:mysqli_escape_string() 期望参数 1 为 mysqli,给定 null
【问题讨论】:
你是否在同一个文件中使用了两次require_once('../../Connections/db.php');
?
您忘记显示$dbcon
变量的初始化
您认为_once
位是什么意思?
这就是问题所在,据我所知,值并未取消。应该执行,但不是。 @Jon Stirling 我知道如果它已经包含它就不会再包含了。我想知道的是,为什么函数中没有连接变量?
@Rocktale 我想你刚刚回答了你自己的问题。该文件已包含在其他地方,因此该文件不会包含在函数范围内。
【参考方案1】:
您正在使用 require_once('../../Connections/db.php');
函数之外。因此 Connections/db.php
已经包含在内,因此即使您再次通过 require_once
包含它,它也无法在函数中使用。
见difference
解决方案:删除第二个 require 调用,而是将变量传递给函数:GetSQLValueString($theValue, $dbcon, ....)
【讨论】:
所以 a 解决方案是删除第二个 require 调用,而是将变量传递给函数:GetSQLValueString($theValue, $dbcon, ....)
@Martin 正确。包括在答案中。谢谢。
是的,它包含在函数之外,但为什么现在函数内部没有可用的连接?我的意思是,整个脚本适用于较旧的 mysql,但不适用于 mysqli。
@Rocktale 您的$dbcon
变量在文件中可用,但不在函数的本地范围内
除非我将它作为@Martin 所说的参数传递,不是吗?是的,这对我来说听起来很合乎逻辑。好吧,在不传递参数时,是否仍然可以像使用“mysql_”一样使用“mysqli_”进行最后一个连接?我猜不是,只是好奇。【参考方案2】:
假设您在此函数之前没有关闭数据库连接,以下应该可以工作:
function pruefe_datum($datum)
if (!function_exists("GetSQLValueString"))
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
global $dbcon;
$theValue = mysqli_escape_string($dbcon, $theValue);
这是一个范围问题。 $dbcon 变量在函数中不存在,第二个 require_once 被忽略且不需要。
【讨论】:
是的,我想这是解决它的最佳方法。我知道这里的其他一些人也已经说明了范围问题,感谢他们所有人!正如我所说,我还在学习。并且旧的“mysql_”-方法不一定需要传递给它的连接,它只需要最后一个可用或尝试打开一个新的,但是“mysqli_”-方法需要一个作为参数传递的连接,这样似乎这就是为什么它可以与旧的“mysql_”一起使用但不适用于我对“mysqli_”的更改的原因。非常感谢! @Rocktale NO.对于这种代码构造,使用global
是个坏主意。它将两个值(函数和数据库变量)结合得太紧密了,很容易导致您出现复杂性问题。 read more about why 。 varlogtim 的这个答案不是最佳实践。 More here
@Martin 好的,我知道这可能会导致设置全局变量出现问题,感谢您的链接。我仍然不明白我还能做些什么来解决我的问题?如前所述,我不想更改我需要的更多代码,但我也希望它能够工作,并且还想了解如何认为事情是正确完成的。那么,我应该将连接变量作为参数传递给我需要它的每个函数,而不是将其声明为全局变量吗?或者我还能做什么?
如果你有很多使用数据库连接的函数,那么你应该简单地创建一个数据库Class
,其中包含这些函数并在类中有一个变量来保存数据库连接。然后,班级中的每个人都可以访问它。关于其他说明;如果您想做最佳实践但又不想编辑代码,那么这有点关键,因为您需要不断开发和重新设计非最佳实践代码,所以有点像想说话但不想说话想要张开嘴.... :-/
@Rocktale 进一步说明,假设您有一组用于处理客户篮子的函数,然后您可以将这些函数全部设置到 basket
类中,并且在该篮子类中您可以定义 (在构造中)一个包含数据库连接的变量,然后从类中的任何函数(称为方法)中使用它。 $basket = new BasketClass($dbcon);
其中dbcon
然后作为变量保存到篮子类中,可以通过$this->basketDbVar
访问以上是关于required_once() 中的变量未定义但可与 require() 一起使用,为啥?的主要内容,如果未能解决你的问题,请参考以下文章
用于 PHP 的 Google API 客户端中的 required_once 问题