I need to change a global variable inside a namespace in PHP.
I'm currently refactoring some legacy code and a section of the code relies on the use of a global variable, which used to be configured in the code I'm refactoring.
I'm now trying to use namespaces on the new refactored code and can access the variable just fine by using \, but I couldn't find a way to change its value.
Sadly, changing the \legacyCode so it doesn't use the global variable is out of question.
Is not using namespaces here the only good solution?
Example:
namespace Namespace;
$GlobalVariable = 123;
abstract class NamespaceClass extends \legacyCode
{
}
// no namespace defined
class legacyCode
{
function doSomething() {
global $GlobalVariable;
echo $GlobalVariable;
// GlobalVariable is undefined
}
}
Thanks in advance.
Related
I want to know if there is a way to namespace values, in a similar way that we namespace functions in PHP.
You can have:
namespace pizza\land;
function turn_oven_on(){}
And you can access that function with pizza\land\hello()
I wonder if there is a way to do something similar for values.
This is not correct, I am just illustrating what I mean:
namespace pizza\land;
namespaced $ingredients = array('pepperoni', 'garlic');
Then access it with $pizza\land\ingredients.
Other parts in the same runtime can do:
namespace pasta\land;
namespaced $ingredients = array('tomato', 'mozzarella');
Then access it with $pasta\land\ingredients.
Of course that doesn't work, but it serves as an example of what I mean.
I know there is the obvious way, which would be to use the Singleton pattern where the constructor sets the value of a public property for the singleton instance (the one and only one instance of the class).
I dislike this setup, and in that case I prefer to go the killer route and just do global $pseudonamespaced_pizza_land_ingredients.
I wonder, is there anything else I can do to achieve this setup using the latest version of PHP (now 8.1)?
Why?
To have the same effect you have with global but at the same time avoid collision.
Well, let's say I am working with some procedural code and I need a value that can be accessed across multiple functions.
So I want to use that value within the realms of that bunch of functions.
I do not want to wrap all those functions into one Class and then use a property for that class, because in that case I just prefer the Singleton or the global.
Also, if not possible. Why not?
I cannot believe that this hasn't been mentioned before as something to consider for integration into PHP. So, there must be a reason for this not being possible, if it isn't. It would be a cool solution for all those codebases that are mostly procedural and use global way too often... ehem... WordPress...
I think this could be a good answer for this question as the goal is to have variable live inside of the namespace, and that OP has overcomplicated the question for no reason.
Assuming that you have a variable named $number in the global scope of a PHP script. Inside a function, we have another variable with the same name $number, and we assign and change values of it within the function. But, the global variable remains unchanged. This is variable scope. In the same way, classes can be namespaced to give it scope.
Consider having a following code:
<?php
namespace Math;
function add($a, $b) {
return $a + $b;
}
const PI = 3.14;
class Geometry {
static function getCircleArea($radius) {
return PI * $radius ** 2;
}
}
First, we declare the namespace. (So, all the classes, interfaces, constants and function below it will be items of that namespace)
Then, we declared a normal function.
Then, a class constant.
Then, a class.
Now let's access to theseMath namespace's items from another file(functions, constants, and classes).
<?php
// includes the Math.php file
// It's like you had all the code of Math.php written here
include_once 'Math.php';
echo Math\add(2,3); // 5
echo Math\PI; // 3.14
echo Math\Geometry::getCircleArea(10); // 314.15
Thanks to #shingo's comment under the question, this is how I now learned that this can be achieved.
// Namespace
namespace whatever;
// Class with static property
class StaticStuff {
static string $variable = 'Hey';
}
// Access it
echo StaticStuff::$variable; // Hey
// Edit it
StaticStuff::$variable = 'Miau!';
// Access it again
echo StaticStuff::$variable; // Miau!
Specifically:
Define a class
With a static property
Inside a namespace
I am kind of confused about using name spaces in php,would try to explain using the problem I have with one of my project
I have a class under a namespace as
namespace BigBlueButton;
class BigBlueButton
{
public function createMeeting($createMeetingParams, $xml = '')
{
//some code
return new CreateMeetingResponse($xml);
}
}
I use it as
use \BigBlueButton;
$bbb = new BigBlueButton\BigBlueButton();
//then I try to reference the variable $bbb in a function but I can't
function easymeet_create_meeting($id) {
// $bbb = new BigBlueButton\BigBlueButton(); I don't want to create a new object here but reference the object I created above,something like this
$bbb=BigBlueButton\bbb;
}
But I can't seem to access the above variable i.e. $bbb , I tried global $bbb ,but $bbb doesn't seem to be in the global namespace, I understand I am trying to access a constant $bbb in the above code, but I showed it anyway to tell what I am trying to do
Namespacing does not extend to variables like that:
In the PHP world, namespaces are designed to solve two problems that
authors of libraries and applications encounter when creating
re-usable code elements such as classes or functions:
Name collisions between code you create, and internal PHP classes/functions/constants or third-party
classes/functions/constants.
Ability to alias (or shorten) Extra_Long_Names designed to alleviate the first problem, improving readability of source code.
http://php.net/manual/en/language.namespaces.rationale.php
Your class declaration is fine, but you've mis-used the use keyword as it should refer to specific classes, not a namespace.
use \BigBlueButton\BigBlueButton;
function easymeet_create_meeting($id, BigBlueButton $bbb) {
/* ... */
}
$bbb = new BigBlueButton();
$result = easymeet_create_meeting(1234, $bbb);
You'll notice that I've also moved $bbb into the function parameters because global state is the devil. It's also type-hinted because why not?
Better yet:
class BigBlueButton implements ButtonInterface {}
class BigRedButton implements ButtonInterface {}
And:
function easymeet_create_meeting($id, ButtonInterface $bbb) {}
$result[] = easymeet_create_meeting(1234, new BigBlueButton());
$result[] = easymeet_create_meeting(5678, new BigRedButton());
And now we're looking at the rudiments of Dependency Injection, which is a good habit to get into.
If I understand it right the problem is not with namespace.
As you said you could try using a global variable for example:
use \BigBlueButton;
global $bbb;
$bbb = new BigBlueButton\BigBlueButton();
function easymeet_create_meeting($id) {
global $bbb;
// you can use it
}
or you can send the variable to the function
function easymeet_create_meeting($id, $bbb) {
}
I do not know the entire problem, but you could also use a singleton design pattern in the class so you always get the same instance every time you use it.
This is a PHP newbie question:
I want to give my class access to my database credentials in an include file: ../config.inc
<?php
$db_info['host']='localhost'; // and so forth
...
?>
Later, in my class source file I have:
<?php
require_once('../config.inc'); // include the above file
public class Foo {
static function Host() {
echo $db_info['host'];
}
}
?>
When try to access the class in other code, I get an error claiming that $db_info is undefined. When I try to move the require_once inside the class scope (after Foo {) I get a syntax error, so apparently one can't use require_once inside the class. What are the best practices when writing class static methods that need access to included data? THANKS.
You have a issue with the scope. Your included variable is available outside your class but not inside your class. The suggested methods should be to pass the variable to the constructor of your class and store it in a member variable of the class.
But since your using the function as static then you can use global but its not best practices to do so. alternatively you can include the file with in the function.
public class Foo {
static function Host() {
require_once('../config.inc'); // include the above fil
echo $db_info['host'];
}
}
Is it possible to define a global function from within a PHP namespace (within a file that has a namespace declaration)? If so, how?
<?php
namespace my_module;
# bunch of namespaced functions
# ...
# then I want to define a global function my_module()
# that is an alias to my_module\mymodule()
It's possible but aside from being bad design, you will have to enclose your code within brackets for each namespace and won't be able to use namespace my_module; Instead it will have to be namespace my_module { ... }.
Example:
namespace my_module {
function module_function()
{
// code
}
}
namespace {
// global namespace.
function my_module()
{
// call your namespaced code
}
}
Functions defined in 'included' files have global scope.
So ( I haven't verified this ) you could put your function declaration in a small file, and include it.
Not quite what was envisaged in the question.
The other way to do it would be to create a local function, and in it use the 'global' keyword, and assign a closure to a global variable - which could then be used 'as a function' wherever you wanted it.
I've certainly done this for ordinary variables, and I see no reason it should not work for closures.
Is there any way to temporary use a namespace ?
I'm using a library to create forms and it uses namespaces, the problem is that I usually want to create a form in the middle of a page, which is thus in the global namespace. Then if I want to call any function of this library I have to prefix everything with Namespace\
Isn't there any way in PHP to do something like this :
Blabla global namespace
strlen('test'); // 4
namespace Namespace
{
test();
}
More global PHP
And have it refer to Namespace\test ?
http://www.php.net/manual/en/language.namespaces.importing.php
<?php
namespace foo;
use My\Full\Classname as Another;
// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;
// importing a global class
use ArrayObject;
$obj = new namespace\Another; // instantiates object of class foo\Another
$obj = new Another; // instantiates object of class My\Full\Classname
NSname\subns\func(); // calls function My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject
// without the "use ArrayObject" we would instantiate an object of class foo\ArrayObject
?>
This is about the closest you can get - there's no way to change the default namespace temporarily.
I know this is an old question, and while the accepted answer answers the question as it was asked, I feel like what the OP is really asking is "Can I use items in the global namespace from another namespace. The answer here is a clear and simple yes.
Imagine two classes (one in the global namespace, another in its own:
ClassInGlobal.php
<?php
class ClassInGlobal
{
public static function doStuff()
{
echo 'I do some stuff';
}
}
ClassInNamespace.php
<?php
namespace App\Classes;
class ClassInNamespace
{
public function callDoStuff()
{
\ClassInGlobal::doStuff();
}
}
The above executes fine. All that is required is a leading slash to specify the fully qualified global namespace. Additionally, you could add a use ClassInGlobal declaration right after the namespace declaration and omit the leading slash.
This might translate into the original question by abstracting the namespaced functions into a class Then you could modify the OP's code slightly to acheive this:
require './Namespace/Utilities.php';
Blabla global namespace
strlen('test'); // 4
\Namespace\Utilities::test();
More global PHP
Hope that helps someone coming here looking for that.