I am working on the AWS documentation which uses Guzzle framework. I have to deal with namespaces here and I am not able to get it working. I went through the docs and examples and understood that we can have packages for projects using namespaces.
I went ahead and tried a simple example, but unsuccessful. Here's the example: this is the index.php:
use My\Full\Classname as Another; //Also tried use My\Full\Classname
$obj = new Another; //with $obj = new Classname;
echo $obj->add();
I have Classname.php in the directory structure like this My->Full->Classname.php:
<?php
class Classname{
public static function add(){
return 2+2;
}
}
?>
I am trying to call the function in index.php but getting error:
Fatal error: Class 'Another' not found in C:\wamp\www\guzzleEx\index.php on line 19
which is the line where I instantiate the Classname object $obj = new Another;
What is the mistake i am making? Is there any INI that needs to be updated or any other config issue? How can I make the code working? If you use the normal include for Classname.php it works fine.
Namespaces need to be explicitly declared, they do not come from a certain directory structure.
So if you do not have a line that reads namespace My\Full; in front of your class Classname, then your class is not in any namespace, but in the root namespace.
Thus you cannot use it as \My\Full\Classname, but \Classname or even Classname directly.
Related
I`m use namespace in my project. But namespace not works.
file index.php
use \Folder\Aa;
Aa::test();
$test = new Aa();
file Folder/Aa.php
namespace Folder;
class Aa
{
static function test()
{
$a = 3;
echo $a;
}
}
Write me Fatal error: Class 'Folder\Aa' not found in /home/ademidko/www/first.local/index.php
I`m changes namespace in Аа.php, write "use \Folder" and other -> but not works
PHP does not load classes dynamically by itself. In order to you to be able to use your class your code have to look like this:
require_once('Folder/Aa.php');
use \Folder\Aa;
Aa::test();
$test = new Aa();
There are many possible ways how to make this work without manually writing require or require_once. One of them is to use composer's autoloading functionality (details can be found here: https://getcomposer.org/doc/04-schema.md#psr-4).
You can also consider writing your own autoloader (more details here: http://php.net/manual/en/function.spl-autoload-register.php)
I have a lot of SDKs which have the same class names so I have moved them into folders and created namespaces. These sdks are generally used to access APIs.
//directory e.g. vendor/company/sdk/files
vendors/ebat/feeback/environment.php
I then have completely separate libraries which I have created myself which contain any methods I need to interact with these sdks. also namespaced.
//directory e.g.
library/marketplace/ebay/feedback.php
Not sure what the correct terminology is but within these libraries are some global objects e.g. stdClass and ReflectionClass which a cant seem to access/find.
feedback.php
namespace Marketplace\Ebay;
class Feedback extends \Ebat\Feedback\EbatNsFeedback_Environment {
//simple example
public function new_ReflectionClass($obj){
return new ReflectionClass($obj);
}
}
Now if I were to try and call this method
$this->marketplace->ebay->feedback->new_ReflectionClass(new stdClass()));
this error is shown.
Fatal error: Class 'Marketplace\Ebay\ReflectionClass' not found
When I add a backslash
return new \ReflectionClass($obj);
it then gives me this error
Fatal error: Class 'Ebat\Feedback\ReflectionObject' not fount
How can I access the native/global ReflectionClass class, all similar questions seem to be fixed by adding a backslash.
Adding a leading \ is the correct way to access top-level namespaces/classes.
But it seems you're running in to a similar error elsewhere - note that your 2nd fatal error is about ReflectionObject, not ReflectionClass. Do you have other code that tries to access ReflectionObject?
Also, note that you can also import these namespace-less classes if you don't want to prefix every reference with a \
namespace Marketplace\Ebay;
use \ReflectionClass;
class Feedback extends \Ebat\Feedback\EbatNsFeedback_Environment {
//simple example
public function new_ReflectionClass($obj){
return new ReflectionClass($obj);
}
}
This is a sample code:
sample code
I want to call it in another page:
include 'root of class file';
$r = new ImagineResizer();
I got this error:
Fatal error: Class 'ImagineResizer' not found in C:\WampDeveloper\Websites\example.com\webroot\images.php on line 13
Also call the function:
$r->resize('c:/test1.jpg', 'c:/test2.jpg');
As seen in your sample code the class is located in another namespace :
<?php
namespace Acme\MyBundle\Service;
use Symfony\Component\HttpFoundation\File\File;
use Imagine\Image\ImagineInterface;
use Imagine\Image\BoxInterface;
use Imagine\Image\Point;
use Imagine\Image\Box;
class ImagineResizer {
//-- rest of code
}
To use a class in another namespace you need to point out where the file is :
First include the class (manual or with autoloading)
Then u can create an instance in 2 ways. First way with the use-keyword
use Acme\MyBundle\Service\ImageResizer;
$object = new ImageResizer();
Or point to the class absolute :
$object = new \Acme\MyBundle\Service\ImageResizer();
Hopefully, this will help you out some:
Make sure you include the actual file - not just the folder where it lies.
Make sure that the file you're calling the class from uses the same namespace as your class file. If it doesn't, you have to call the class using the full namespace.
Profit.
The namespaces really had my patience go for a spin when I started using them, but once you're used to it it's not too hard. I would recommend using an autoloader though. It's a bit of a hassle to set up, but once it's done it helps out a bunch.
Namespaces: http://php.net/manual/en/language.namespaces.php
Autoloader: http://php.net/manual/en/function.spl-autoload-register.php
Im building a custom CMS and have setup an autoloader, and have adapted use of namespaces. For the most part things are loading properly, but in certain cases PHP reports that it cannot find the class, the class file has been included.
Once a file is included (using require), it should be instanced as well.
The parent controller is instanced, then the child controller attempts to instance a few of its own dependencies.
$this->auth = new \Modules\Auth\RT\Auth();
This will look for a file at /modules/auth/rt/auth.php, and it does and the class is instanced properly.
The namespace of Auth is:
namespace Modules\Auth\RT;
The auth class tried to load its own dependencies, a model in particular.
$this->auth_model = new Models\ModelAuth();
Here the file to be included is at /modules/auth/rt/models/modelauth.php
It is included successfully, but this is where PHP says I cannot find this class.
Fatal error: Class 'Modules\Auth\RT\ModelAuth' not found in /Users/richardtestani/Documents/ShopOpen-Master/shopopen/modules/auth/rt/auth.php on line 12
What would cause the class from not being instanced even though the file is included?
Thanks
Rich
try this:
$this->auth_model = new Modules\Auth\RT\Models\ModelAuth();
try this:
$this->auth_model = new \Modules\Auth\RT\Models\ModelAuth();
OR
$this->auth_model = new Models\ModelAuth();
when you are in this namespace \Modules\Auth\RT
There was a Missing \ , so the code trys to include the namespace twice;
FOR REAL ;)
I am builded a new object in my file without namespaces:
new My\Validator();
Above, in the same file I have got __autoload():
function __autoload($className)
{
var_dump($className);
}
The __autoload() function prints
'My\My\Validator'.
Where is the double 'My' come from?
It is adding the My namespace because you are probably inside the My namespace already when you create the object with new My\Validator().
namespace My;
$obj = new My\Validator();
will be translated to:
$obj = new My\My\Validator();
Since you are inside the My namespace already you can:
either just call new Validator()
or call new \My\Validator()
The beginning \ will tell PHP to look into the global namespace.
On a side note, it is considere good practice to use spl_autoload_register instead of __autoload, because you can set multiple autoloader callbacks.