That is simple for you, but I can't understand the difference (if it exist) between two "name" of this same class:
First if I use php function (get_class()) for some entity I get something like structure to directory to class of this object (App\Module\Class).
Second: If i want to get some data form db I have to use a repository name as AppModule:Class
So is there any method to transform first naming to second?
I don't know how you naming this two methods, I am sorry for my mistakes.
If you use ClassName::class where ClassName is whatever a class is, you'll obtain the class FQCN (Fully Qualified Class Name; in your example, for instance, App\Module\Class)
I suggest to use ClassName::class every time you can instead of VendoBundle:Class convention
This will work only if you use PHP >= 5.5 btw, but I hope you do!
Related
I have a project that includes a PHP file that defines a class named Response and I'm auto-loading Guzzle via composer (which also defines it's own Response class)
The question is do I run the risk that PHP might get confused as to which Response class it should use? If I use Response by itself I don't run the risk that it will somehow fetch the Guzzle class unless I do a use statement right?
I think it's fine unless I do the use statement but I just wanna be sure.
You don't have any risk of conflicts, that's why PHP Namespaces exist!
Although the short name of both classes are the same, their FQCN (Fully Qualified Class Name) are different, so there's no chance of getting confused.
Guzzle's Response class is:
\Guzzle\Http\Message\Response
Your class would be something like:
\MyApp\Response
(or just \Response if you didn't set a namespace for it, which is a very bad practise!)
You can use either of them in your classes, or even both, as long as you set an alias for one of them:
use \MyApp\Response;
use \Guzzle\Http\Message\Response as GuzzleResponse;
// ...
$myResponse = new Response();
$guzzleResponse = new GuzzleResponse();
As long as the classes got individual namespaces.
Composer (and its autolaoder) will resolve the namespace with the classname.
So if you use your own class ("Class1") and the foreign class ("Class2") with the same classname ("Classname") with different namespaces e.g.
namespace \Me\MyPackage\Classname
namespace \Guzzle\Classname
you will be fine. If you wanna create an instance of one of the classes just type the full qualified namespace e.g.
$var1 = new \Me\MyPackage\Classname();
Symfony2 docs say that I should use alias shortcut 'ByBundle:myEntity' for entity path:
$em->getRepository('ByBundle:myEntity');
But this string literal is not usefull - no refactoring, no fast and auto renaming of the entity class in IDE.
I use magic method ::class
$em->getRepository(\ByBundle\Entity\myEntity::class);
The Question: am I doing this right?
In fact the Symfony2 core team is using the ::class method for example for adding form field types like so: $builder->add('name',TextType::class,array(...)) since Symfony v2.8 i guess there's nothing wrong the way you do it.
UPDATE:
This allows your IDE to throw an exception if the linked entity class namespace would change and you will be able to recognize this while the development process. That is definitely a "it's better to be safe than sorry" way of how to map the entity instead of having the full qualified namespace or even the alias as a string.
Yes. Using class reference is always better than string refence.
Using string usually means there is algorithm, that converts string to the class.
IDE friendly is also desired.
I want to write a small add on for an existing CMS. To do so, I need to extend a class from that CMS' code.
My code will be written inside its own namespace, while the CMS' code does not use namespacing, which basically means it exists inside the global namespace.
Inside my code, I create a new stdClass:
$var = new stdClass();
With that code is place, it always produces a fatal error:
Fatal error: Class 'MyNamespace\something\StdClass' not found in /some/rather/long/path/to/class.php on line 123
Creating the stdClass like this solves that problem:
$var = new \stdClass();
Since I am still pretty new to namespaces, I am not exactly sure what the problem here is?
My guess is that in the first example, the stdClass would be created in the namespace of my class. This actually means the constructor of a class called stdClass existing in my namespace would be called, but since that class does not exist, an error is thrown.
In the second example, I signalize that I want to instantiate the class called stdClass from the global namespace, which somehow suddenly makes sense.
If anyone could elaborate what is happening here I would be very happy.
You appear to understand the concept behind namespaces, and you are headed in the right direction on your analysis of what is happening.
When you are working inside of a namespace you are able to refer to names as unqualified, qualified, and fully qualified.
When you make a namespace you are telling PHP to organize (and resolve) the names of your classes, function, methods, etc. away from the same scope where the built-in PHP code lives along with any other code behind its own namespace. It is away to organize your code and avoid naming collisions among libraries and built-in PHP functions.
Here is a brief on how names get resolved:
If you are trying to resolve a name within the same namespace you can use the unqualified name. So for class \Foo\Bar\Baz you can use new Baz(); as long as you are in namespace \Foo\Bar.
If you are trying to resolve a name that is lower in the same parent namespace you can use the qualified name. So for class \Foo\Bar\Baz you would need to use new Bar\Baz(); if you were in namespace \Foo.
If you are trying to resolve a name that is not in your namespace or is in the global namespace (built-in PHP stuff) then you must use the fully qualified name. If you are in namespace \Foo\Bar and you want to make use of something like the mysqli class you would need to call it by its fully qualified name. e.g. new \mysqli() Your question above is a perfect example that illustrates this. Likewise, if you need to access a class in a totally different namespace you would also need the fully qualified name: new \Third\Party\AppClass();
So to summarize, you are right, the built-in stdClass does not exist in your namespace, therefore you need to access it by the fully qualified name. The reason you must do thing this way had to do with conforming to the rules PHP uses when resolving names.
If you ever need to find out what namespace you are in it will be in the __NAMESPACE__ constant.
In case you haven't already read it, here is the documentation on name resolution in PHP: http://php.net/manual/en/language.namespaces.rules.php
The code is evaluated in your namespace and stdClass doesn't exist there. You are effectively answering your own question with your guess.
Your guess is correct. Look at the comments in "class references" section of Example #1 on this page.
http://php.net/manual/en/language.namespaces.rules.php
I have two classes written on different php file having same name. I want to load one at a time. For this i search many places .. and i found this piece of code. I want can anybody elaborate what does it doing?
$class= $this->controller.'Controller_';
$controller=new $class($this->registry);
Please explain more if you can ...
You can refer to a class by using a variable. So in this case, a class name is put together using the value of $this->controller and the constant string 'Controller_'. So if $this->controller is 'Foo', $class becomes 'FooController_'.
The second line instantiates an object of this class and passes a value to it's constructor.
So in the end, this code does:
$controller = new FooController_($this->registry);
The advantage is, that the 'Foo' part is variable. So for instance, you could map an url path to a class, so that example.com/foo is handled by a fooController and example.com/bar is handled by a barController.
So this is not what you want. This is loading different classes with different names.
If you have two classes with the same name, you must make sure that you only load the file of the class you want to use. You cannot use two classes with the same name, unless they are in different namespaces. So if you have two files, foo1.php and foo2.php, and each contains a class named foo, then you'll need to include the proper file. But I think this is bad design. Normally you shouldn't have to choose between classes of the same name, unless maybe in a test case, where a unit test can load a mock version of a real class.
I'm trying to create a mock to satisfy a typehint with this code (Mockery):
return \Mockery::mock('\Contracts\Helpers\iFileSystemWrapper');
or this (PHPUnit):
return $this->getMock('\Contracts\Helpers\iFileSystemWrapper');
But the mock returned is called Mockery\Mock Object or Mock_iFileSystemWrapper_a5f91049. How am I supposed to type check this when it isn't an instance of what I need at all with either framework?
Why exactly is the mock framework trying to load the real class? If I wanted the real class I would include the real class.
This problem has slowed me down so many times when writing tests I'm about to just toss type hinting out the window and check class names instead, or simply use production objects as mocks are a pain to use.
I just experimented with an existing test of my own, and by changing the interface namespace name from one that exists to one that doesn't exist, I got exactly the same as what you describe (using phpunit). My mock object had the class name Mock_ViewInterface_c755461e. When I change it back to the correct interface name, it works fine.
Therefore I would say that either:
You are trying to use an interface name that doesn't exist (e.g. a typo or missing namespace component).
Your library code isn't being loaded for some reason, e.g. autoloading is not setup correctly in your unit test bootstrap.
You need use a special function to check base class.
Somthing like this:
$mock = $this->getMock('MyClass');
$this->assertInstanceOf('MyClass', $mock);