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.
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 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.
I'm trying to figure out how namespaces work in PHP but have a hard time understanding when a global namespace prefix is required. Take the following example:
index.php
namespace MySpace;
require_once 'file.php';
Test::hello();
hi();
file.php
class Test {
public static function hello () {
echo 'hello';
}
}
function hi() {
echo 'hi';
}
This won't work but writing \Test::hello() instead will and echoes both "hello" and "hi".
Why isn't the \ required for hi() as well?
http://php.net/manual/en/language.namespaces.fallback.php
Using namespaces: fallback to global function/constant
Inside a namespace, when PHP encounters an unqualified Name in a class
name, function or constant context, it resolves these with different
priorities. Class names always resolve to the current namespace name.
Thus to access internal or non-namespaced user classes, one must refer
to them with their fully qualified Name [...]
For functions and constants, PHP will fall back to global functions or
constants if a namespaces function or constant does not exist.
I get a parse error when trying to use a name space inside my own function
require('/var/load.php');
function go(){
use test\Class;
$go = 'ok';
return $go;
}
echo go();
From Scoping rules for importing
The use keyword must be declared in the outermost scope of a file (the
global scope) or inside namespace declarations. This is because the
importing is done at compile time and not runtime, so it cannot be
block scoped
So you should put like this, use should specified at the global level
require('/var/load.php');
use test\Class;
function go(){
$go = 'ok';
return $go;
}
echo go();
Check the example 5 in the below manual
Please refer to its manual at http://php.net/manual/en/language.namespaces.importing.php
From the manual:
The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations.
From what I gather a lot of people are getting this when including a separate function file and trying to use the static method inside that function.. For example in index.php
namespace foo/bar
require('func.php')
f();
and in func.php
function f() {
StaticClass::static_method();
}
you simply need to declare namespace foo/bar in func.php (same like how you declared it in index.php) so instead of the above it should look like:
namespace foo\bar
function f() {
StaticClass::static_method();
}
to avoid errors like:
Fatal error: Uncaught Error: Class 'StaticClass' not found in func.php
It's obvious now but I was confused why func.php does not carry over the namespace declaration inside the file that 'requires' func.php
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.