8

I have been trying this for hours now - and I can't seem to find any posts that work. I am adding custom php classes to the Symfony2 vendor directory.

For example (copied other vendor structure):

vendor/mylib/mylib/src/Mylib/Lib/Class.php

I then updated the root composer.json by adding:

"require": {
    "mylib/mylib": "@dev"
},

I also created a composer.json in vendor/mylib/mylib which contained:

{
    "name": "mylib/mylib",
    "type": "library",
    "description": "My Libraty",
    "keywords": ["library"],
    "autoload": {
        "psr-0": { "Mylib\\": "src/" }
    },
    "minimum-stability": "dev"
}

I have added a namespace in Class.php:

namespace MyLib\Lib;

In one of my bundles I have added the below:

use MyLib\Lib\ClassName as ClassName;
class Cms extends ClassName
{}

The error I am getting is:

FatalErrorException: Error: Class 'MyLib\Lib\MyClass' not found in C:\xampp\htdocs\My_CMS\src\Cms\CmsBundle\Entity\Cms.php line 13

What am I doing wrong?

2
  • Have you run composer dump-autoload after adding your lib to composer.json? Commented Aug 25, 2013 at 22:20
  • Just tried that and its still giving me the same error :( Commented Aug 25, 2013 at 22:31

4 Answers 4

10

You really should be using service containers which is basically the symfony way to load classes.

Here's why:

  1. Namely, a service is never constructed until it's needed.
  2. Best practice for reuse of code.
  3. Separating each piece of functionality in your application.
  4. Since each service does just one job, you can easily access each service and use its functionality wherever you need it.
  5. Each service can also be more easily tested and configured since it's separated from the other functionality in your application.
  6. This idea is called service-oriented architecture and is not unique to Symfony or even PHP.

http://symfony.com/doc/current/book/service_container.html

A Service Container (or dependency injection container) is simply a PHP object that manages the instantiation of services (i.e. objects).

So basically symfony will handle instantiation of classes for you in your controller. All you need to do is the following:

Add a folder under your path called Libraries --> src/AppBundle/Libraries

Add the class to this folder with a namespace at the top. My example is:

    <?php

namespace AppBundle\Libraries;

class MyRecommendations{


    public function __construct(){

    }

    public function init(){
        die("init");
    }


}

Then add a file called services.yml to your app. app/config/services.yml

Put the following code in it do not use tabbing in the yml file

services:
    myrecommendations:
        class:        AppBundle\Libraries\MyRecommendations
        #arguments:    [specialparamhere]  #constructor parameters here

Then add the third line resources: services.yml to your config.yml file.

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }

At the top of your controller when using just add the use statement

use AppBundle\Libraries\MyRecommendations;

Now call your code

$test = $this->get('myrecommendations');
            $test->init();

echo's out

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

1 Comment

I'm voting this answer up because this is the quickest and most understandable explanation about easily setting up a service that I've read up to this day. Thanks, it helped a lot.
4

In php classes are autoloaded via __autoload

Symfony takes care about it in it's Class Loader but in fact it works the same way. There is no background scaning all directories so you have to add your namespace manually.

You need to add in your autoload.php file:

$loader->add('NAMESPACE','/path/to/vendor');

3 Comments

I am still getting the error after adding the below to app/autoload.php - $loader->add('MyLib','/../vendor/mylib/mylib/src/MyLib/Lib');
OK - Its working now. With: $loader->add('MyLib\Lib', realpath(DIR.'/../vendor/mylib/mylib/src'));.. Was a path typo.. Thanks a lot :)
You may want to add the third boolean flag true if you want to append your namespace to the existing list created by composer.
0

If one have another project that use autoloader to load its classes, for example SimpleSAML, and want to use it in class in another namespace:

namespace Study\UserBundle\Service;

require_once "/full_path/simplesaml/lib/_autoload.php";


use SimpleSAML_Configuration;
use SimpleSAML_Auth_Simple;
use SimpleSAML_Auth_State;

class SimpleSAMLLogin {

Comments

0

The last answer is correct: https://stackoverflow.com/a/27768442/2400373

I work for me however is important add that this is correct but if you before you install the library en autoload. In my case in Symfony 3.2.x I added my library en composer.json:

"autoload": {
    "psr-4": { "": "src/" },
    "classmap": [ "app/AppKernel.php", "app/AppCache.php","**src/AppBundle/juanitourquiza/pagopayphone/library"** ]

And after this instruction:

composer update

Then all is well.

Regards

2 Comments

"The last answer" can change or be deleted. You should include the share link. (Also, not quite sure what you are saying)
Thanks, I now add the link

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.