我最近在问题中看到了如何创建包含 url id 的全局函数?在您的一个答案中,您提到全局变量通常是不好的做法。
作为参考,有这个问题: 为什么认为使用全局变量是不好的做法?有很多令人困惑的文档,一些受到严重批评的全局函数,除非我对这个主题感到困惑并且我的全局变量不是全局的。
在其中一个答案中说全局变量会创建隐藏的依赖关系,当涉及到大型应用程序时,提到您甚至不知道/记住/不清楚您拥有的对象及其关系。
函数中的全局变量是一个很好的实用程序,当与PHP
&一起工作时,我认为它们是这样的HTML
。
在这个例子中,我看不出这是一个不好的做法,除非其中存在一些安全漏洞。
$connect = new mysqli('127.0.0.1', 'tu_usuario', 'tu_contraseña', 'sakila');
function user(){...
global $connect; //conexión a la base de datos
// Código de la consulta
}
HTML中的函数结果
<div><?php user();?></div>
你能向我解释一下什么是不好的做法吗?
哪些变量被确定为全局变量?
主题中涉及PHP 保留字。global $conexion;
注意:有一个问题为什么它被认为是一种不好的做法,也许它与同一个主题相关,但问题彼此非常不同,有一种使用方法但没有针对编程初学者的示例,很多没有实践的理论会令人困惑,简而言之,答案是更多地看到解决方案的坏面,即使我有编程经验,对我来说,这么多行之间的东西非常令人困惑。
切入正题,从严格意义上讲
PHP
为什么要避免 PHP 中的全局变量?
全局变量比局部变量更昂贵。因为它强制 PHP 扫描整个变量范围直到找到它,所以函数内的局部变量总是比全局变量快。
它们降低了代码的可重用性。原因是所有项目都没有相同的全局变量,因此使用全局变量的函数很难重用该函数。在 OOP 中,它们直接破坏了封装。
使用全局变量的函数可能会产生误导,这与前一点有关。参数作为全局变量在主体中传递的函数似乎不需要参数,这可能导致代码混乱和模棱两可。如果函数需要参数,最好直接传递它们。
通过使用局部变量而不是全局变量,与其他变量命名冲突的可能性较小,因为局部变量只存在于局部范围内。
全局变量可以从程序的任何部分修改,这可能会引起很多麻烦,因为很难知道它是在何时何地被修改的。
例子在最后。
哪些变量被确定为全局变量?
全局变量是在程序的一般范围(变量范围)中定义的那些变量 。另一方面,我们有超全局变量,除了上述之外,还可以从程序的任何部分直接访问,它提供了多个超全局变量,其中$GLOBALS是访问全局范围变量的第二种方法。
PHP
全局函数
如果我们参考全局函数,在手册中我们可以找到以下内容:
用户自定义函数
全局类方法
这样,一个类的方法不能声明为全局的,所以在没有先实例化类的情况下不能直接在全局范围内使用,基本上不存在全局方法。但是,它
PHP
允许我们声明静态方法,这些静态方法可以在任何范围内访问,在类的名称和双冒号前加上静态方法(miClase::miMetodo( )
)。例子
示例点 3
示例点 5:
使用全局变量的好处
PHP
是微乎其微的,为了方便而使用它们只不过是含糊不清。在考虑如何设计一个信息系统时,如何让它随着时间的推移和不同的人可维护,是将其划分为更简单的子系统,这些子系统往往会形成具有单一职责的逻辑单元(程序) ,它们的行为就好像它们是一个“组件”。另一方面,尽量减少这些程序之间的依赖关系。
只要我们能更好地满足这两个目标,新程序员就能越快理解系统的操作,更改、替换或删除任何程序的复杂性就越低。
变量主要落在依赖方面。
一个函数的局部变量在函数内部诞生和消亡,没有其他程序知道它的存在。因此,如果函数被修改并且该变量更改其名称、数据类型、值范围或被删除,则更改的影响仍然存在于函数内,并且只要该函数继续接收相同的数据作为参数并继续为了提供相同的结果,对系统的其余部分来说,使用该局部变量所做的事情是透明的。
现在,假设这个函数使用一个全局变量,这是一个在系统级别定义的变量,所有程序、函数、过程都可以访问它,无论它们是否使用它(读取和/或修改它)。这意味着它不再只是可以读取或修改该变量的函数。
全局变量在函数和其他也使用相同全局变量的函数、程序或过程之间创建了依赖关系,这使得维护更加复杂。也就是说,如果我们必须消除该函数,更改变量的数据类型或其值范围,我们必须检查该变量用于确定更改影响的任何地方,并且在许多情况下这种类型的依赖关系导致对功能的修改,会在系统的其他部分带来更多的修改,这些修改乍一看似乎是无关的。
如果在具有数百个程序和数千行代码的系统中考虑到这一点,并且添加了程序员的轮换,很可能其中一些更改不会被检测到,并且会以完全意想不到的方式出现在生产中甚至在外观上。与所做的修改无关,这会导致错误,而且纠正起来也非常麻烦。
第一版
关于将与数据库的连接保持在全局变量中。
如果使用在程序终止之前不会关闭的单个连接,则无论您将其保存到全局变量还是将其作为系统范围的参数传递,该变量本质上已经是全局的,并且不能免除上述问题。例如,在进行维护时,有人可能会无意中在某处引入连接关闭,或者在错误的位置提交或回滚事务,并影响稍后在程序流程中完成的其他功能(举几个例子)。
另一种选择是在每次需要完成查询时打开一个连接,并在执行后关闭它。
但是打开到数据库的连接在时间方面是昂贵的。然后两种选择的利弊通常是平衡的,如果利大于弊,则决定将连接保留为全局资源,并采取一些其他措施来减轻问题的发生。
一个例子是最小化使用连接的函数。可能会有一个函数或一系列知名函数接收/n 查询的参数,执行它并将结果返回给调用函数而不是调用函数。每个函数直接使用全局变量。
在权衡利弊的问题上,有几件事情需要考虑,以便采取一种或另一种方式。其中包括:数据库驱动的实现细节,是否使用连接池,系统是否运行单线程或支持并发。
在 PHP 的情况下,我知道它在单线程中运行,最方便的是打开连接并保持打开状态。因此,保持全局连接是一种可行的替代方案,并且可以通过减少使用该连接的功能数量来降低风险。
作为一个像坏习惯这样的主观问题,可能会有不同的意见。通常,当您开始编程时(无论使用哪种语言),您都倾向于将所有代码包含在单个函数(main)中,因为它看起来更实用(起初)。
当开发规模较小且自我管理时,在某些情况下使用全局变量可能更实用。但是当开发规模很大,文件很多时,有时会丢失变量的跟踪或可追溯性,当它们是全局时更是如此。
使用全局变量也有点破坏开发的模块化,就像在 C 中使用 GOTO。
使用尽可能少的全局变量是一个好习惯,但在大多数情况下,使用它们根本不会做任何事情。
同样的事情发生在我身上,我想在任何时候使用我的连接变量、用户数据……但是代码的可读性差让我感到沮丧,我正在研究 PHP 对变量和函数的使用最后我得出一个结论(或多或少正确,但它有效),我会告诉你。
PHP 可以说是在活动圈子中工作,其中一个是程序的主线程,其中声明了所有变量和函数,另一个是包含对象(类)。主线程的所有变量和函数都是全局的,可以直接调用(函数),也可以通过“全局”声明(变量)调用。这些类在实例化或调用它们(静态类)时遵循主线程,它们也可以通过创建“命名空间”包含在其他操作圈中,它们将声明的“公共”函数附加到主线程(默认情况下,如果你不要声明另一件事)并将“私人”保持为自己的。
或多或少(广义地说)PHP 的全局和私有部分是如何工作的。现在,我们关心的问题是使代码更具可读性并且不丢失变量的全局部分。这可以通过“静态”类函数来实现,静态函数不需要按顺序实例化其关联对象要被调用(就像一个静态变量一样),您只需要使用“include”或“require”加载对象。
在这里我们可以看到如何使用这些静态对象,MyConfig 类有一个静态变量 $user 和一个静态函数 abbreviation(),如果类被加载,这些都是全局的,可以从程序的任何地方调用,不好的地方是静态函数和方法是它们是“静态的”并且不允许在没有实例化的情况下调用对象方法,例如:
这会给我们一个错误,因为静态方法无法访问 MyConfig 对象的变量(不是静态的)。但是静态变量就像一个全局变量,例如:
在前面的例子中,MyConfig 对象声明并赋值给 $clientIp 变量,然后由 getRealIP() 函数修改,在随后的两次回显中,返回的值是相同的,因为函数修改了方法变量。
如果我们将所有这些应用于与数据库的连接问题,我们将有:
数据库和 PDO 连接器具有足够的功能,因此我们不需要保持多个连接到数据库 (fetch_all),这样我们就可以在我们喜欢的地方使用方法和全局变量。
此外,通过这种方式,代码更具可读性、有序性和可扩展性。
正如您已经解释的那样,使用全局变量会以某种方式破坏封装。当我们想到对象时,它们必须具有高内聚和低耦合,以便您可以重用代码。但是当你谈论一个系统时,并不是所有的东西都可以成为一个对象,代表问题的“领域范围”,你还必须解决“解决方案的范围”,值得冗余,为此使用全局变量。出于这个原因,大多数面向对象的语言都允许使用共享数据,而无需为其创建对象。在我看来,错误在于您以不受控制和未经研究的方式使用此机制。
例如,您可能希望有两个全局变量 SESSION['tmpUserName'] 和 SESSION['tmpUserId'] 可以从程序中的任何位置访问。为了增加控制,您可以将这些变量封装在一个类中,并始终从一个对象访问它们。
现在您知道您的全局变量被封装在一个类中,您可以通过从“tmpVal”类以外的其他地方访问它来违反“合同”,就像从类外部进行数据库调用一样。
另一方面,您可以利用一种简单的机制来解决一个简单的问题,而不会使它变得复杂。
正如您可能在上面的答案中读到的那样,使用全局变量通常被认为是不好的做法,不仅在 PHP 中,而且在几乎所有编程语言中。
不使用全局变量的一些原因...
我将这些观点作为以下链接中文章的基础:http ://wiki.c2.com/?GlobalVariablesAreBad
关于数据库连接,它们确实很昂贵,最好不要打开和关闭;但是,一些数据库管理器(Oracle 和 SQL Server)实现了连接池,通过它优化了打开和关闭过程,基本上是重用它们(一种连接缓存)。