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.
Related
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!
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 have a unique situation that is hard to debug.
I need to set a global string inside a php class that is not strictly defined as a global, the class must be in another file.
The file.php with the string has simply this:
//this cannot be changed
$foo_version = '1.1.1';
The example.php file trying to access this string must use a class:
class Bar extends Task {
public function main() {
require_once('../file.php');
//global $foo_version; this doesn't work
// update the database with this string, does not work
update_option( 'db_field', $foo_version );
}
}
How can I get the $foo_version to return something inside the class?
Also nothing can be defined/done outside the class.
If you include the file, and the variable is in the include file, you can just use it.
class Bar extends Task
{
public function main() {
require_once('../file.php');
update_option( 'db_field', $foo_version );
}
}
What you have is a variable $foo_version and it can easily be changed. You can use define to make it a constant instead see PHP DOC
define("FOO_VERSION", "1.1.1");
class Bar extends Task {
public function main() {
require_once ('../file.php');
update_option('db_field', FOO_VERSION);
}
}
If you insist Replace require_once with require your code would work because PHP will check if the file has already been included, and if so, not include (require) it again.
If you have used this in another class definitely it would not work. Change your code to the following
class Bar extends Task {
public function main() {
require ('../file.php');
update_option('db_field', $foo_version);
}
}
B.php:
class B
{
function show() { echo 'works'; }
}
A.php
class A
{
public static function defineB()
{
include "b.php";
}
}
A::defineB();
$b = new B;
var_dump($b);
object(B)#1 (0) { } ,
if without A::defineB(); - Fatal error: Class 'B' not found ,
if define class without including another file - Fatal error: Class declarations may not be nested ,
is it bug ?
It is not a bug, it is default and correct behaviour.
You should include files before using them. If this gives you too much pain, you could use http://www.php.net/manual/en/language.oop5.autoload.php or http://www.php.net/manual/en/function.spl-autoload-register.php in the beginning of your code.
In PHP you can not nesting classes (as in Java) - so you got "Class declarations may not be nested". The key word is namespace. Including class B from method of class A does not affect the name of class A that is still... "A" and not "B\A", "B.A" or sth. :)
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