Is the global namespace prefix only required for classes? - php

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.

Related

Use php namespace inside function

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

Classes - require conflict in constructor

I'm coding a Wordpress plugin and I'm not sure regarding the function name conflict..
I have a file named test_handling.php which contains the following content :
function testing() { echo 'test'; }
I included this file in a class constructor (file named testcls.class.php) :
class TestCls {
function __construct() {
require_once('test_handling.php');
testing();
}
function otherfunction() {
testing();
}
// ...
}
In this case, I would like to know if the testing() function is only available in the TestCls class, or can it create conflicts if an other WP plugin has a function with the same name ?
Even with the same name, the functions will have different scope if defined as class method. To make a call to a regular function you will do the following:
testing();
and the result will be:
'test'
the class method need an instance of the class or be statically called. To call the method class you will need the following formats:
$class->test();
or
OtherPlugin::test();
To sum up, the function test will be different if defined as class method. Then, you will not have conflicts.
Other way to encapsulate your function and make sure you are using the right one is with namespaces. If you use a namespace in your test_handling.php
<?php
namespace myname;
function testing(){echo 'test';}
?>
You will access the function test like this:
<?php
require_once "test_handling.php";
use myname;
echo myname\testing();
Now you are sure about the function you are calling.
When a file is included, the code it contains inherits the variable
scope of the line on which the include occurs. Any variables available
at that line in the calling file will be available within the called
file, from that point forward. However, all functions and classes
defined in the included file have the global scope.
from include in PHP manual
Which means that yes, you can have conflicts.

Is there a namespace aware alternative to PHP's class_exists()?

If you try using class_exists() inside a method of a class in PHP you have to specify the full name of the class--the current namespace is not respected. For example if my class is:
<?
namespace Foo;
class Bar{
public function doesBooClassExist(){
return class_exists('Boo');
}
}
And Boo is a class (which properly autoloads) and looks like this
namespace Foo;
class Boo{
// stuff in here
}
if I try:
$bar = new Bar();
$success = $bar->doesBooClassExist();
var_dump($success);
you'll get a false... is there an alternative way to do this without having to explicitly specify the full class name ( i.e. class_exits('Foo\Boo') )?
Prior to 5.5, the best way to do this is to always use the fully qualified class name:
public function doesBooClassExist() {
return class_exists('Foo\Boo');
}
It's not difficult, and it makes it absolutely clear what you're referring to. Remember, you should be going for readability. Namespace imports are handy for writing, but make reading confusing (because you need to keep in mind the current namespace and any imports when reading code).
However, in 5.5, there's a new construct coming:
public function doesBooClassExist() {
return class_exists(Boo::class);
}
The class pseudo magic constant can be put onto any identifier and it will return the fully qualified class name that it will resolve to.......

Define global function from within PHP namespace

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.

What is a namespace in PHP?

I read an article about namespaces in PHP. But I don't get what they are used for?
<?php
namespace MyProject {
// Regular PHP code goes here, anything goes!
function run()
{
echo 'Running from a namespace!';
}
}
I also read the PHP.net manual about it, but didn't quite get it.
I had a tough time as well, just think of it as a way to help the compiler resolve names.
So there is no ambiguity.
You could have two developers writing completely different classes but with same type identifier.
The class names could be the same. Grouping in namespaces helps the compiler/interpreter will remove the ambiguity.
So namespace Developer1.CoolClass is quite different from namespace Developer2.CoolClass
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.
PHP Namespaces provide a way in which to group related classes, interfaces, functions and constants.
Check Here for details
Namespaces are a way to group your related classes in packages.You can assume namespaces as folders where you keep your files,in a way that both can have the files with same name but different (or same) without any ambiguity.
file1.php
<?php
namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo() {}
class foo
{
static function staticmethod() {}
}
?>
file2.php
<?php
namespace Foo\Bar;
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
static function staticmethod() {}
}
/* Unqualified name */
foo(); // resolves to function Foo\Bar\foo
foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO
/* Qualified name */
subnamespace\foo(); // resolves to function Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // resolves to class Foo\Bar\subnamespace\foo,
// method staticmethod
echo subnamespace\FOO; // resolves to constant Foo\Bar\subnamespace\FOO
/* Fully qualified name */
\Foo\Bar\foo(); // resolves to function Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // resolves to class Foo\Bar\foo, method staticmethod
echo \Foo\Bar\FOO; // resolves to constant Foo\Bar\FOO
?>
Consider your write your own class, lets called it Foo. Someone else writes also a part of the project and he calls one of his classes also Foo.
Namespaces solve this problem.
Example:
Namespace MyClasses;
Class Foo
{
}
NameSpace HisClasses;
Class Foo
{
}
$myfoo = new MyClasses\Foo();
$hisfoo = new HisClasses\Foo();
Namespaces are used to isolate functions and class declarations in order to make libraries and "helpers" (files containing functions) more portable. By putting a library in a name space, you reduce the chances of your class names colliding with what an author who may want to use your library may want to call their classes For example, you can have multiple classes named "user" if they're in separate namespaces.

Categories