Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony " 'use' statement for another namespace?" issue

I have a problem with namespaces in connecting my entity class to an abstract-type class.

I needed to create an AbstractType Class I called BlogFactory. I intent to use it in my the createAction function of my BlogController.php Entity class for creating blog entries.

My BlogFactory class is created in the Form/Blog directory of my bundle, as the tree structure shows.

.
.
.
src/Blogger/BlogBundle/
├── Controller
│   ├── BlogController.php
│   └── PageController.php
├── DataFixtures
│   └── ORM
│       └── BlogFixtures.php
├── Entity
│   ├── Blog.php
│   ├── Blog.php~
│   └── Enquiry.php
├── Form
│   ├── Blog
│   │   ├── BlogFactory.php
│   │   └── Factory.php
│   └── EnquiryType.php
├── Resources
│   ├── config
│   │   ├── config.yml
│   │   ├── routing.yml
│   │   └── services.yml
.
.
.

In the BlogController.php entity class, I include the following use instruction:

namespace Blogger\BlogBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Blogger\BlogBundle\Form\Blog\BlogFactory;

class BlogController extends Controller{
.
.
.

with the following createAction function:

public function createAction(){   
        $form = $this->createForm(new BlogFactory(), new Blog(), 
            array(
                'action' => $this->generateUrl('blog_create'),
                'method' => 'POST',
            )
        );

        $form->add('submit', 'submit', array('label'=>'Create'));
        return $form;
    }

Here is the code in my BlogFactory class:

namespace Blogger\BlogBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class BlogFactory extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title');
        $builder->add('author');
        $builder->add('blog');
        $builder->add('image');
    }

    public function getName()
    {
        return 'newblog';
    }
}

However, my problem is I get the following error:

The autoloader expected class "Blogger\BlogBundle\Form\Blog\BlogFactory" to be defined in file "/var/www/Symfony-Blog/src/Blogger/BlogBundle/Form/Blog/BlogFactory.php". The file was found but the class was not in it, the class name or namespace probably has a typo

I'm quite stuck and not sure how to resolve this.

UPDATE:

As suggested by Gnucki, I added namespace Blogger\BlogBundle\Form\Blog; to my BlogFactory.php and use Blogger\BlogBundle\Form\Blog\BlogFactory; to BlogController.php, and got the slightly different error below:

Attempted to load class "Blog" from namespace "Blogger\BlogBundle\Controller".
Did you forget a "use" statement for another namespace?
like image 794
sisko Avatar asked Dec 29 '14 01:12

sisko


1 Answers

There is a problem of mapping between your directories and namespaces:

You say that the class BlogFactory is in Form/Blog/BlogFactory.php and you define the class in the namespace Blogger\BlogBundle\Form.

You should use this namespace for your class BlogFactory:

namespace Blogger\BlogBundle\Form\Blog;

Then specify these use statements in your controller:

use Blogger\BlogBundle\Form\Blog\BlogFactory;
use Blogger\BlogBundle\Entity\Blog;

Explanation:

In a simple PHP application, you use some require or include to include files into each other. But it is really boring. Instead, you can use an autoload function to handle that. Symfony2 implements it in a manner that a namespace is mapped on a directory in a logical way. For instance, class Blogger\BlogBundle\Entity\Blog can be found in /Blogger/BlogBundle/Entity/Blog.php.

If you want to use the class in another one (with another namespace (so another directory)), you can use for example:

new \Blogger\BlogBundle\Entity\Blog();

or:

use Blogger\BlogBundle\Entity\Blog;

new Blog();

Imagine, you are in another namespace whitout that use:

namespace Blogger\BlogBundle\Controller;

new Blog();

The class Blog will be interpreted as class Blogger\BlogBundle\Controller\Blog.

namespace Blogger\BlogBundle\Controller;

use Blogger\BlogBundle\Entity\Blog;

new Blog();

Now, with the use, Blog will be interpreted as Blogger\BlogBundle\Entity\Blog.

See namespaces in PHP for more informations.

like image 101
Gnucki Avatar answered Nov 05 '22 13:11

Gnucki