I have recently seen in the question How to create a global function that contains the id of the urls? that in one of your answers you mention that global variables are generally bad practice.
For reference there is this question: Why is it considered bad practice to use global variables? there is a lot of confusing documentation, some badly criticized global functions, unless I'm confused on the subject and my global variables are not global.
It is said in one of the answers that global variables create hidden dependencies, when it comes to large applications, mentioning that you don't even know/remember/are not clear about the objects you have and their relationships.
Global variables within functions are a great utility, I consider them that way, when working together with PHP
& HTML
.
In this example I don't see how it can be a bad practice, unless there is some security vulnerability in them.
$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
}
Function result in HTML
<div><?php user();?></div>
Could you explain to me what a bad practice would be?
Which variables are determined as a global variable?
PHP reserved words global $conexion;
are involved in the theme.
Note: There is a question why it is considered a bad practice, perhaps it is linked to the same topic, but the question is very different from each other, there is a way to use it but no examples for beginners in programming, a lot of theory without practice would be confusing, In short, the answer is about seeing more of the bad side of a solution, it is for me something very confusing between so many lines, even though I have programming experience.
Getting to the point and speaking from a strictly
PHP
Why avoid global variables in PHP?
Global variables are more expensive than local variables . Since it forces PHP to scan the entire variable scope until it is found, a local variable inside a function will always be faster than a global one.
They reduce the reusability of the code . The reason is that all projects do not have the same global variables, so a function that uses global variables makes it difficult to reuse that function. in OOP they directly break the encapsulation.
Functions that use global variables can be misleading , this is linked to the previous point . A function whose argument is passed in the body as a global can appear to need no arguments, which can lead to confusing and ambiguous code. If a function requires arguments, it is better to pass them directly.
By using local variables instead of global ones, there is less chance of naming conflicts with other variables, since local variables only exist in the local scope.
Global variables can be modified from any part of the program , something that can cause many headaches since it will be difficult to know where and when it has been modified.
Examples at the end.
Which variables are determined as a global variable?
Global variables are those variables that are defined in the general scope of the program (scope of variables) . On the other hand we have the superglobals that in addition to the above can also be accessed from any part of the program directly, it
PHP
provides multiple superglobal variables among them $GLOBALS which is a second method to access the variables of the global scope.global functions
If we refer to global functions , in the manual we can find the following:
User-defined functions
Global class methods
As such, the methods of a class cannot be declared as global, so they cannot be used directly in the global scope without first instantiating the class, basically global methods do not exist. However, it
PHP
allows us to declare static methods , these static methods can be accessed in any scope, prefixing the name of the class and the double colon to said static method (miClase::miMetodo( )
).examples
Example point 3
Example point 5:
The benefit of using global variables in
PHP
is minimal and using them for convenience is nothing more than vagueness.When considering how to design an information system, the way to do it so that it is maintainable over time, and by different people, is to divide it into simpler sub-systems tending to arrive at logical units (programs) that have a single responsibility, that behave as if they were a “component”. And on the other hand to minimize the dependencies between these programs.
To the extent that we can better meet these two objectives, the faster a new programmer can understand the operation of the system, and the less complex it is to change, replace, or eliminate any of the programs.
Variables mainly fall on the side of dependencies.
A variable local to a function is born and dies inside the function and no other program knows of its existence. So, if the function is modified and that variable changes its name, data type, value range, or is deleted, the impact of the change remains within the function and as long as this function continues to receive the same data as a parameter and continue to deliver the same result, it is transparent to the rest of the system what has been done with that local variable.
Now, suppose that this function uses a global variable, this is a variable that is defined at the system level and all programs, functions, procedures have access to it whether they use it (read and/or modify it) or not. That means that it is no longer just the function that can read or modify that variable.
The global variable creates a dependency between the function and the rest of the functions, programs, or procedures that also use the same global variable, and this makes maintenance more complex. That is, if we have to eliminate that function, change the data type of the variable, or its range of values, we have to check everywhere where that variable is used to determine the impact of the change, and in many cases this type of dependencies causes that a modification in a function, bring about more modifications in other parts of the system that at first sight seem to be unrelated.
When you think about systems with hundreds of programs and thousands of lines of code, plus the turnover of programmers, it is likely that some of these changes will go undetected and surface in production completely unexpectedly and even in appearance. not related to the modification that was made, which contributes to making errors that are also very cumbersome to correct.
EDITION I
Regarding keeping the connection to the database in a global variable.
If a single connection is used that doesn't close until the program terminates, the variable is already global in nature whether you save it to a global variable or pass it as a system-wide parameter, and it's not exempt from the mentioned problems. For example, when doing maintenance, someone may inadvertently introduce connection closure somewhere, or commit or rollback a transaction in the wrong place and affect other functions that are done later in the program flow ( to give a couple of examples).
The other option is to open a connection every time a query needs to be done and close it after it has been executed.
But opening connections to the database is expensive in terms of time. Then the pros and cons of both options are usually balanced and if the pros outweigh the cons, it is decided to leave the connection as a global resource and some other measures are taken to mitigate the occurrence of problems.
An example is minimizing the functions that use the connection. It would be the case of having a single function or a family of well-known functions that receive/n the parameters of the query, execute it and return the result to the calling function vs. that each function use the global variable directly.
In this matter of balancing the pros and cons, there are several things to consider in order to go one way or the other. These include: implementation details of the database driver, whether connection pools are used, and whether the system runs single threaded or supports concurrency.
In the case of PHP, I understand that it runs in a single thread and the most convenient thing is to open the connection and keep it open. So maintaining a global connection is a viable alternative and risks can be mitigated by reducing the number of functions that use the connection.
Being a subjective issue like a bad practice, there may be different opinions. Generally when you start programming (regardless of the language) you are tempted to include all the code inside a single function (main) because it just seems more practical (at first).
When development is small, and self-managed, it may be more practical to use global variables in some situations. But when the development is large, and there are many files, sometimes the tracking or traceability of the variables is lost, even more so when they are global.
Using global variables also breaks the modularity of development a bit, it's like using the GOTO in C.
It's good practice to use as few global variables as possible, but in most cases, using them simply won't do anything.
the same thing happened to me, I wanted to make use of my connection variables, user data, ... at any point but the poor readability of the code was frustrating me, I was studying the use that PHP made of the variables and functions and at Finally I reach a conclusion (more or less correct, but it works), I will tell you about it.
PHP could be said to work in circles of activity, where one would be the main thread of the program, and all the variables and functions declared in it, and another one that includes the objects (classes). All variables and functions of the main thread are global and can be called directly (functions) or through the "global" declaration (variables). The classes adhere to the main thread when instantiating or invoking them (static classes), they can also be included in other circles of action by creating "namespaces", they attach their declared "public" functions to the main thread (by default if you do not declare another thing) and maintain the "private" as their own.
More or less (broadly speaking) how the global and private part of PHP works. Now, the problem that concerns us is to make the code more readable and not lose the global part of the variables. This can be achieved with the "static" class functions, a static function does not need to have its associated object instantiated in order to be called (just like a static variable), you just need to have the object loaded with either "include" or "require".
Here we can see how to use these static objects, the MyConfig class has a static variable $user and a static function abbreviation(), these are global if the class is loaded and can be called from anywhere in the program, the bad thing about static functions and methods is that they are "static" and do not allow calling object methods without instantiating it, for example:
This would give us an error, since the static method would not have access to the variables (not static) of the MyConfig object. But a static variable is like a global variable, example:
In the previous example, the MyConfig object declares and assigns a value to the $clientIp variable, which is then modified by the getRealIP() function. In the two subsequent echoes, the value returned is the same, since the function modifies the value of the method variable.
If we apply all this to the problem of the connection to the database, we would have:
The databases and the PDO connector have enough functions so that we do not need to keep more than one connection open to the database (fetch_all) and in this way we will have methods and global variables to use where we please.
In addition, in this way the code is much more readable, ordered and expandable.
As you have already explained the use of global variables would break encapsulation in some way. When we think of objects they have to have high cohesion and low coupling so that you can reuse code. But when you talk about a system, not everything can become an object that represents the "scope of the domain" of the problem, you also have to solve the "scope of the solution", worth the redundancy, for which the use of global variables. For this reason, most object-oriented languages allow the use of shared data without the need to create objects for it. The mistake, in my opinion, is that you use this mechanism in an uncontrolled and unstudied way.
For example, you might want to have two global variables SESSION['tmpUserName'] and SESSION['tmpUserId'] which can be accessed from anywhere in the program. to increase control you can encapsulate these variables in a class and always access them from an object.
Now you know that your global variables are encapsulated in a class, you could violate the "contract" by accessing it from somewhere other than the "tmpVal" class in the same way you would by making DB calls from outside a class.
On the other hand, you take advantage of a simple mechanism to solve a simple problem without making it complex.
As you may have read in previous answers, it is generally considered bad practice to use global variables, not only in PHP, but in almost any programming language in general.
Some reasons not to use global variables...
I took these points as the basis of an article in the following link: http://wiki.c2.com/?GlobalVariablesAreBad
En relación a las conexiones de Base de Datos, es cierto que son caras y resulta mejor no estar abriendo y cerrando; sin embargo, algunos gestores de base de datos (Oracle y SQL Server), implementan un pooling de conexiones, a través del cual se optimizan los procesos de apertura y cierre, básicamente reutilizándolas (una especie de cache de conexiones).