Use php namespace inside function - php

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

Related

Is the global namespace prefix only required for classes?

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.

Using "use" within a function?

I'm trying to make the following work:
function flosoftdedicated_api_init() {
require_once 'resources/vendor/autoload.php';
use \Ovh\Common\Ovh;
....
$ovh = new Ovh($config);
return $ovh;
}
function flosoftdedicated_ClientArea($params) {
global $ovh;
$ovh = flosoftdedicated_api_init();
....
}
but I get the error:
Parse error: syntax error, unexpected T_USE in ..../flosoftdedicated.php on line 35
Line 35 being the use statement.
Is it not possible to use a namespace in a function? Do I need to assign the same namespace?
It's because you cannot declare it from within a function. From PHP: Using Namespaces:
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.
You'll have to move it outside of any function or class.
The "use" keyword can not be declared inside the function or method.
from php.net http://www.php.net/manual/en/language.namespaces.importing.php#98908

PHP class unable to access included variables

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'];
}
}

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.

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.

Categories