I posted some questions previously regarding the use of Namespaces in PHP and from what I got, this example code I have below should be working.
However I am getting errors when I try to use Namespace in PHP like this. Here is the first error when running the code below as is...
Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6
E:\Controller\testing.php File
<?php
use \Controller;
include('testcontroller.php');
$controller = new Controller;
$controller->show();
?>
E:\Controller\testcontroller.php File
<?php
use \Library\Registry;
namespace Controller
{
class Controller
{
public $registry;
function __construct()
{
include('E:\Library\Registry.class.php');
$this->registry = new Registry;
}
function show()
{
echo $this->registry;
echo '<br>Registry was ran inside testcontroller.php<br>';
}
}
}
?>
E:\Library\Registry.class.php File
<?php
namespace Library\Registry
{
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
}
?>
As you can see I tried to make it as simple as possible just to get the Namespace part working. I have tried different variations and cannot seem to figure it out.
Even when using use statement, you need to specify the namespace of the class you are trying to instantiate. There are a lot of examples here: http://www.php.net/manual/en/language.namespaces.importing.php
To understand it better, I will describe to you how it works. In your case, when you do use \Controller, the whole Controller namespace becomes available to you, but not the classes that are in this namespace. So, for example:
<?php
include('testcontroller.php');
use \Controller;
// Desired class is in namespace!
$controller = new Controller\Controller();
// Error, because in current scope there is no such class
$controller = new Controller();
$controller->show();
?>
Another example:
testcontoller.php:
<?php
namespace Some\Path\To\Controller;
class Controller
{
function __construct()
{
}
function show()
{
echo '<br>Was run inside testcontroller.php<br>';
}
}
?>
testing.php:
<?php
include('testcontroller.php');
use \Some\Path\To\Controller;
// We now can access Controller using only Controller namespace,
// not Some\Path\To\Controller
$controller = new Controller\Controller();
// Error, because, again, in current scope there is no such class
$controller = new Controller();
$controller->show();
?>
If you wish to import exactly the Controller class, you need to do use Controller\Controller - then this class will be accessible in your current scope.
Its not that good idea to name the namespace, like the class, because it is confusing (and I think this is what happens here). There moment you define the alias via use Controller this referenes to either a class \Controller, or the namespace \Controller, but your class, because it is within the namespace, is named \Controller\Controller 1
use Controller;
$class = new Controller\Controller;
or
$class = new \Controller\Controller;
or
use Controller\Controller;
$class = new Controller;
The idea is, that the moment you try to access a class with its relative name it tries to map the "first part" against any alias defined using use (remeber use MyClass is the same as use MyClass as MyClass. The thing after as is the alias).
namespace MyNamespace\MyPackage\SomeComponent\And\So\On {
class MyClass {}
}
namespace Another {
use MyNamespace\MyPackage\SomeComponent; // as SomeComponent
$class = new SomeComponent\An\So\On\MyClass;
}
As you can see PHP finds SomeComponent as the first part and maps it against the SomeComponent-alias the line above.
You can read more about it in the manual about namespaces.
1 Its called "Full-qualified classname", if you name a class with its complete name.
When you put a class Controller in the namespace Controller, then you have to reference it that way:
$controller = new Controller\Controller();
\Controller would be a class in the global (default) namespace, i.e. as if you used no namespace at all.
Strangely I have found that in my example code from the Question above, if I change all the Namespace's that are defined to something like MyLibrary so it would be like this code below...
E:\Library\Registry.class.php File
<?php
namespace MyLibrary
{
class Registry
{
function __construct()
{
echo 'Registry.class.php Constructor was ran';
}
}
}
?>
Then when I use use MyLibrary\Registry; in another file, I am able to access it how I had planned...
$this->registry = new Registry;
The reason this is very strange to me is this now makes a class name appear to be a Namespace as well. So I would not need to set a Namespace to 'MyLibrary\Library' to access the Registry instead I would do it like I showed in this answer to be able to access it with just calling the name of the class.
I hope this makes sense and helps someone else. I will not accept this as the answer as I am hoping someone with more know-how will come in and post a better Answer with explanation
try
<?php
use \Library\Registry;
namespace Controller;
class Controller
{
public $registry;
function __construct()
{
include('E:\Library\Registry.class.php');
$this->registry = new Registry;
}
function show()
{
echo $this->registry;
echo '<br>Registry was ran inside testcontroller.php<br>';
}
}
?>
and
<?php
namespace Library\Registry;
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
?>
First off, I believe you are using composer or composer is initialised in your project. If so, check composer.json file for your autoload, psr-4 definition. For example, if the root of your application is "App", then in your psr-4, you should be doing "autoload": { "psr-4": { "App\\": "./" } },
Furthermore, remember to clear composer cache and dump-autoload from the terminal as follows:
composer clear-cache
composer dump-autoload
Related
I can not understand why php gives me an error
"Fatal error: Cannot declare class rex\builder\RexBuilder, because the
name is already in use in /var/www/site2.dev/App/rex/RexBuilder.php on
line 12"
RexBuilder static class, and it is called only 1 time.
I did a search on the project, no longer classes with the same name.
<?php
namespace rex\builder;
require_once 'Router.php';
use rex\router\Router;
error_reporting(E_ALL);
ini_set('display_errors', 1);
class RexBuilder {
public static function collector($array) {
$router = new Router();
foreach ($array as $key => $val) {
$router->get($val->getMethod(), $val->getInterfaces(), $val->getHandler());
}
$router->init();
}
}
?>
Call the class in index.php
RexBuilder::collector(array(
new BuildModel('POST', '/api/v1/user/register', new \api\register\Registration()),
new BuildModel('POST', '/api/v1/user/login', new \api\login\Login())));
More This class is not used
The error is thrown because of the use rex\router\Router; duplicate classes.
When you are writing use namespace.. it means you can go directly to that namespace like it is your current namespace
Lets take a look at the next code:
We'll create a file and declare that it belongs to namespace classes\a
//file: a.php
<?php
namespace classes\a;
class A{
}
now lets create another file b.php (and declare it belongs to namespace classes\b but it means nothing for the example)
namespace classes\b;
require_once "a.php";
use classes\a; //Notice that I'm using this namespace, it means I can use it directly
class A{
}
Generates the error
Fatal error: Cannot declare class classes\b\A because the name is already in use in
We have to solutions possible:
First: remove the use tag and write the namespace directly
class A{
function __constructor(){
$instance = new classes\a\A();
}
}
Second, give it alias
use classes\a as out_a;
class A{
function __constructor(){
$instance = new out_a\A();
}
}
For your code, just remove the use or give it an alias.
The problem is certainly because you include the RexBuilder.php file two times instead of one.
If you call the file by this way : include('RexBuilder.php'); or this way require('RexBuilder.php'); please change it by include_once('RexBuilder.php'); or require_once('RexBuilder.php'); which only allows ONE call of the file.
I'm trying to run this code on the same file:
namespace Foo1\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo1';
}
}
namespace Foo2\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo2';
}
}
use Foo1\Bar\SubBar;
$foo1 = new SubBarClass;
use Foo2\Bar\SubBar;
$foo2 = new SubBarClass;
The ideia is to change namespaces and echo the related value.
But it's returning the following error:
( ! ) Fatal error: Cannot use Foo2\Bar\SubBar as SubBar because the name is already in use in C:\wamp\www\xxx\namespaces.php on line 30
Line 30: use Foo2\Bar\SubBar;
How can I interchange namespaces on the same file?
Thks!
use keyword is used to import that namespace to be accessed in your current file scope. It does not act as a namespace "instance constructor".
You're current under Foo2\Bar\SubBar namespace. Like a directory of classes, while you're here, you should access other namespaces from the root (\):
$foo2 = new SubBarClass;
$foo1 = new \Foo1\Bar\SubBar\SubBarClass;
There is no need to use use for those namespaces (although you can, specially when they share parent namespaces), they are already declared in the same file you're using them.
For more information about this, consider reading the manual, where it describes using multiple namespaces in the same file.
This happens because the last defined namespace is the one currently active.
So, when I type:
use Foo1\Bar\SubBar;
I'm still on the last defined namespace: Foo2\Bar\SubBar.
Hence, when I type:
use Foo2\Bar\SubBar;
I'm trying to use the currently active namespace. That's why the Fatal error is returned.
On possible solution is:
namespace Foo1\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo1';
}
}
namespace Foo2\Bar\SubBar;
class SubBarClass {
public function __construct() {
echo 'From Foo2';
}
}
use Foo1\Bar\SubBar;
$foo1 = new SubBar\SubBarClass;
echo '<br>';
$foo2 = new SubBarClass;
Cheers!
I created a common.php for my all the global function. When I run my first function {{Common::test()}}
It's working fine But I can not use model in it.
namespace App\library;
{
class Common {
public static function test()
{
echo "Yes";
return "This comes from Common File";
}
public static function getCmsBlocks()
{
$model = Modelname::all();
if($model){
echo "asdad";
}else
{
echo "sadasd";
}
}
}
}
I don't get my output when I run {{Common::getCmsBlocks()}}
If your model is in different namespace than App\library you will need to prefix the model class name with its namespace, otherwise PHP will try to load App\library\Modelname which might not be what you need.
Replace
$model = Modelname::all();
with
$model = \Your\Model\Namespace\Modelname::all();
If you use your Modelname class in multiple place in declared namespace, you can import/alias that using use statement so that you can refer to that class by classname in your code:
namespace App\library;
use Your\Model\Namespace\Modelname;
{
class Common {
public static function getCmsBlocks()
{
$model = Modelname::all(); //this will work now
}
}
}
There is no way to define global use to bused by all namespaces in your file, as use always refers to the namespace being declared.
As above the answer is perfect but just a few addition if you don't want to include namespace everytime on at start of each file
Use this :
\App\ModelName::all();
\App\ModelName1::update(item);
\App\ModelName2::find(1);
give path like above and there will be no need to use namespace everytime .
Note: above is path to model which is inside App directory . So change accordingly if you are keeping them at separate place .
This is an experiment with PHP namespaces / autoload in a single file.
namespace trust;
class trust_network{
public function __construct(){
print "SUP";
}
}
namespace trust2;
$trust = new \trust\trust_network(); $do = new \test();
function __autoload($class){
require($class.".php");
print $class;
}
So under namespace trust2, I'm calling "\test" - aka I'd like to autoload that class from an external file on a global base. What I wrote does not work. I know that I've got __autoload under a namespace, but how do I declare that on a global basis? Can't include before namespace declaration.
For multiple namespaces in one file you should use the curly bracket syntax:
namespace n1 {
...
}
namespace n2 {
...
}
namespace {
...
}
In the last block you can declare functions in the global namespace. Reference: http://www.php.net/manual/en/language.namespaces.definitionmultiple.php
Autoload is usually so that you can put one class per file. Therefore, you should have the following layout
/index.php
function __autoload($class){
// You may need to convert backslashes in $class to forward slashes
// and strip the first slash, we'll leave the
require($class.".php");
// debug-only: print $class;
}
// Calling new here triggers __autoload to be called
$trust = new \trust\trust_network();
$do = new \test();
/trust/trust_network.php
namespace trust;
class trust_network{
public function __construct(){
print "TRUST_NETWORK";
}
}
/test.php
class test() {
public function __construct(){
print "TEST";
}
}
Note that you should use spl_autoload_register instead since it allows multiple systems to hook in their own autoload behavior. As of PHP 5.3, you can do the following
spl_autoload_register(function ($class) {
require($class.".php");
});
I work a lot in PHP but I never really understand the namespace method in PHP. Can somebody help me here? I have read on php.net's website its not explained good enough, and I can't find examples on it.
I need to know how I can make code in sample version.
namespace: sample
class: sample_class_1
function: test_func_1
class: sample_class_2
function: test_func_2
function: test_func_3
Like this?
<?php
namespace sample
{
class Sample_class_1
{
public function test_func_1($text)
{
echo $text;
}
}
class Sample_class_2
{
public static function test_func_2()
{
$c = new Sample_class_1();
$c->test_func_1("func 2<br />");
}
public static function test_func_3()
{
$c = new Sample_class_1();
$c->test_func_1("func 3<br />");
}
}
}
// Now entering the root namespace...
// (You only need to do this if you've already used a different
// namespace in the same file)
namespace
{
// Directly addressing a class
$c = new sample\Sample_class_1();
$c->test_func_1("Hello world<br />");
// Directly addressing a class's static methods
sample\Sample_class_2::test_func_2();
// Importing a class into the current namespace
use sample\Sample_class_2;
sample\Sample_class_2::test_func_3();
}
// Now entering yet another namespace
namespace sample2
{
// Directly addressing a class
$c = new sample\Sample_class_1();
$c->test_func_1("Hello world<br />");
// Directly addressing a class's static methods
sample\Sample_class_2::test_func_2();
// Importing a class into the current namespace
use sample\Sample_class_2;
sample\Sample_class_2::test_func_3();
}
If you're in another file you don't need to call namespace { to enter the root namespace. So imagine the code below is another file "ns2.php" while the original code was in "ns1.php":
// Include the other file
include("ns1.php");
// No "namespace" directive was used, so we're in the root namespace.
// Directly addressing a class
$c = new sample\Sample_class_1();
$c->test_func_1("Hello world<br />");
// Directly addressing a class's static methods
sample\Sample_class_2::test_func_2();
// Importing a class into the current namespace
use sample\Sample_class_2;
sample\Sample_class_2::test_func_3();