I'm programming a website with PHP using Symfony2.
I defined a class MainContent in file MainController.php
And I had to use this class in other controller file named SecurityController.php
Although both of these classes are defined in the same namespace, it gave the error:
Class 'MainContent' not found...
So I tried to define the class again in SecurityController.php but result is:
Cannot redeclare class 'MainContent...'
I don't understand, it is either declared or not.
In fact I'm a C# programmer and maybe I'm confused because of some differences between these languages.
Symfony uses so-called autoloading. Since your class is not defined in it's own file, following the rules for auto-loading, it cannot be loaded, hence the class not found. But if you define the class, then script is processed successfully, other file that defines the same class is included, and the collision (cannot redeclare class) is generated.
The possible solutions are:
Define the class in one place (best outside the controller) and use include_once / require_once whenever you need it
Make the class actually a Symfony helper class, so autoloading actually works
Whenever you are declaring the class, use
if(!class_exists('ClassName')) {
class ClassName {}
}
Related
having a bit of a strange problem. I keep on getting this error
UploadPicture has colliding constructor definitions coming from traits
But none of my traits have constructors and neither does my UploadPicture class
Not sure if it could be these at the top of my PictureTrait?
use Imagine\Image\Box;
use Imagine\Image\ImageInterface;
use Orchestra\Imagine\Facade;
Pastebin of files
UploadPicture.php
PictureTrait.php
I found the problem.
The class was called UploadPicture but I have a function inside PictureTrait called uploadPicture, changing the function name has fixed it.
I start getting below error after defining a second controller class PostController in different bundle of the same project with the same vendor name.
Fatal error: Cannot redeclare class
Amce\Bundle\CrudzBundle\Controller\PostController in
C:\xampp\htdocs\community\src\Amce\CrudzBundle\Controller\PostController.php
on line 350
I understand that this error means that I have the same name for two classes (OOP). But why even if I have a different bundle with different vendor part, I keep having this error? Does it mean that Synfony2 disallows having two controller classes with the same name in all situations?
Your expert explanations are always appreciated.
I assume the namespace of the culprit class is:
namespace Amce\Bundle\CrudzBundle\Controller
However the file path is:
C:\xampp\htdocs\community\src\Amce\CrudzBundle\Controller\PostController.php
If you copy/pasted the original class, you may have forgotten to change the namespace.
The autoloader would check the this directory for a class that doesn't exist (because of said namespace), however before that, it will have discovered the exact same namespace/class previously.
In PHP 5.3, the namespace is incorporated into the class name. It's important to remember there is no distinction between them, because they are combined at compile time.
Despite the fact you can call __NAMESPACE__ to get the current namespace, in reality this is not performing a dynamic introspection of the code, but instead the magic constant was converted to a constant string at compile time.
The same is true with classes, the namespace becomes part of the class name, and that is how the class is indexed in the internal reference table.
So be mindful of namespaces.
Is it possible use multiple classes under the same namespace, in the same file? I want to do something like this:
<?php
namespace MyNamespace\Helpers\Exceptions
use Exception;
class CustomException1 extends Exception{}
class CustomException2 extends Exception{}
class CustomException3 extends Exception{}
to avoid using one single file for each custom exception class.
The problem is, when I try to use, in another class, one of the custom exceptions,
use MyNamespace\Helpers\Exceptions\CustomException1;
the CustomException1 class is not found. Any ideas?
I don't think there's anything syntactically wrong with doing this, but I don't think any PSR-4 compliant auotloaders will be able to find a class that is not in it's own dedicated file since the standard is that the name of a file a class belongs in is the same as the name of the class itself:
The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.
Because of this, if you want to use this approach you will have to ensure to include that class file manually whenever you will need those classes to be defined (basically, anytime you want to throw / catch any of those exceptions).
An alternative is to define the classes you want to inside of another class' file that you are absolutely certain will always be autoloaded prior to any invocation of any new CustomExceptionN statements. You will probably find in the majority of cases it is a lot more trouble trying to remember to first be sure to autoload Class1 before using Class2 than it is to just follow the standard and include each class in it's own file located at the proper namespace path.
I have create my own MVC framework which is PSR-0 compliant atm. and uses php-ActiveRecord as ORM.
I have found an issue where I from a controller called User, which exists in the namespace TapMVC\Application, tries to call an ActiveRecord model ALSO called User but exists in the namespace TapMVC\Db like so:
namespace TapMVC\Application;
use TapMVC\Db;
class User extends Controller {
function index() {
print_r(Db\User::find('all'));
}
}
This gives the following error:
Cannot redeclare class TapMVC\Application\User in
/path/to/project/app/Controllers/user.php on line 12
Where line 12 is the prototype/declaration of the User-controller.
Why can't i do this? I thought that if your classes where i different namespaces and had a namespace prefix on instantiation it would be ok to have the same name? Also it looks like the data-model is declared before the controller through autoloading (since its the user-controller declaration which triggers the error), so why is there a conflict when the data-model is in namespace TapMVC\Db and not TapMVC\Application where the controllers are?
What i can see, that even though you define different namespaces, PHP will declare the object under the same namespace as the one in the active file, but i am not sure.
Hope someone can help so i dont need to name my data models like so: (ProjectName-prefix)User and edit the database tables in order to have a User-model and a User-controller.
I found the error! :-D
The issue lied in my autoloading functions for controllers, models etc. since i didn't take care of namespaces. So when I tried to load a controller or model named the same, the spl_autoload_register function would start off by checking for controllers, and since my functions ignored the classes namespaces it would i both cases of: TapMVC\Application\User and TapMVC\Db\User find the User-controller class, stop the autoload list, and try to declare it.
This all resolved when i took care of the namespaces and made sure that controllers/models only get loaded as long as they are in the correct namespace. If not the function dose nothing and the spl_autoload_register function continues down the list of autoload functions.
The question was more framework specific than imagined and boiled down to autoloading which i didn't think was the problem... for some reason, and for that i am sorry. Just happy know that I found the error.
I really hope this isn't a duplicate, but here I go:
I use Zend's autoloader to load classes. It seems to work, at least it loads the correct file when instantiating my class (Common_TestTest) which is implemented in Common/TestTest.php. But then I get the following error message:
"Class Common_TestTest could not be found in Common/TestTest.php."
There's nothing in TestTest.php other than the class:
<?php
class Common_TestTest extends PHPUnit_Framework_TestCase
{
public function testTesting() {
$this->assertTrue(true);
$this->assertFalse(true);
}
}
I tried dumping get_declared_classes at the end of the file, everything looks fine, Common_TestTest is one of the declared classes - but the exception is still thrown when leaving the file.
The funniest bit is: When I change the name of the class from Common_TestTest to TestTest the same things happens - only that the error message states the name of the missing class as "TestTest". So it definitely sees the class and reacts to it's presence.
There are 2 possibilities that come to my mind as to what causes the problem:
You have some case-mismatch between class-name and file-name, e.g. Testtest.php
When registering the Namespace you use "Common" instead of "Common_". Zend_Loader_Autoloader does not distinguish between PHP 5.3 style namespaces and ZF-style namespaces (rather Prefix). By appending the underscore you make sure, that your namespace is interpreted as a class-prefix rather than a real namespace.