14

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?
5
  • You should be using use Blogger\BlogBundle\Form\Blog\BlogFactory. With no use the new BlogFactory is being treated as in the same directory. Commented Dec 29, 2014 at 1:54
  • 1
    As in the same namespace. Commented Dec 29, 2014 at 6:47
  • In your controller, you need to use Blogger\BlogBundle\Form\Blog\BlogFactory; or need use whole path in create form new BlogFactory() Commented Dec 29, 2014 at 7:22
  • Thanks for your responses. Would you mind looking over the code again as I'm certain I'm doing what you suggested but I still get the same error. I apologize because I pasted the wrong abstract class first time around - I have now corrected that. Commented Dec 29, 2014 at 10:46
  • you might have forgotten to install a dependency. This also causes "forget a "use" statement" error. Commented Sep 10, 2015 at 10:05

2 Answers 2

20

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Gnucki. I added an update indicating a new error after implementing your suggestion.
Add use Blogger\BlogBundle\Entity\Blog; in your controller.
Thank you. That got it working. Could you offer some explanation so I better understand how this works and how it fix it - next time? Thanks again
I added an explanation. Tell me if it is not clear or if you want some details.
-1

Note: You can transform

$builder->add('title');
    $builder->add('author');
    $builder->add('blog');
    $builder->add('image');

to

$builder
    ->add('title')
    ->add('author')
    ->add('blog')
    ->add('image')
;

1 Comment

Would be nice if you'd explain why (so because method returns object itself).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.