1

My question was asked before. I also would like to access to my global configs (config/{,*.}{global,local}.php) located in my personal libraries (in the vendor directory). The closest answer that I think I found is here. I created function in my class

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'funcservice' =>  function(\Zend\ServiceManager\ServiceLocatorInterface $sm) {
                $config = $sm->get('config');
            }
        )
    );
}

And it works however I can't figure out how to get anything from the result.

$config = $this->getServiceConfig();
print_r($config);

gives me

Array
(
[factories] => Array
    (
        [funcservice] => Closure Object
            (
                [this] => Tools\Model\StandartFuncs Object
                    (
                        [eventIdentifier:protected] => Zend\Mvc\Controller\AbstractActionController

                        [plugins:protected] => 
                        [request:protected] => 
                        [response:protected] => 
                        [event:protected] => 
                        [events:protected] => 
                        [serviceLocator:protected] => 
                    )

                [parameter] => Array
                    (
                        [$sm] => <required>
                    )

            )

    )
)

and from $config = $this->getServiceConfig()->get('locales'); I get

Fatal error: Call to a member function get() on a non-object

Community
  • 1
  • 1
user2047861
  • 115
  • 1
  • 10
  • 3
    But explanation that you need is in error description... $this->getServiceConfig() return an Array, so later you try to call Array->get(); and of course that Array isn't object and you can not call ->get() method... Or I didn't understand a question ? Try $config = $this->getServiceConfig(); $config['locales']; – tasmaniski Sep 16 '15 at 08:52
  • That's the problem. I get array but no config variables in it. – user2047861 Sep 16 '15 at 09:05

2 Answers2

2

Let's assume you have a locales config file locales.local.php:

<?php

return array(
    'hostname' => 'http://apachehost'
);

These global and local config files should be in the config/autoload folder.

Folder structure:

- root
  - config
    - autoload
      - locales.global.php
      - locales.local.php
    - application.config.php

Then you load them using the following line in your application.config.php. Details on this advanced configuration you can read here in the ZF2 documentation

'module_listener_options' => array(
    'config_glob_paths' => array(
        'config/autoload/{{,*.}global,{,*.}local}.php',
    ),
)

Now you can access your config from your ServiceManager instance like this:

$config = $serviceManager->get('Config');

This $config variable is an array. So you cannot access anything with getters. You are supposed to use array notation:

$locales = $config['locales'];

If your really want to use getters then you have to make your configuration to an object. You can do this using the Zend\Config\Config class like this:

$config = new \Zend\Config\Config($config, false);

Now you can access like you wrote in your question:

$config->get('locales');

Update

If you want to load auto config files from a vendor module it is common practice to copy those *.local.php and/or *.global.php files that come with the module to the autoload folder and edit the copied files according to your needs.

Wilt
  • 41,477
  • 12
  • 152
  • 203
  • Thank you for reply. I'm using described workflow. In application modules (like `/module/Customers/src/Customers/Controller/CustomersController.php`) it works fine. I can access config variables by `$config = $this->getServiceLocator()->get('Config');` However this does not work when class is located in `\vendor`directory: `Fatal error: Call to a member function get() on a non-object in [...]/vendor/Tools/src/Tools/Model/StandartFuncs.php` – user2047861 Sep 16 '15 at 15:49
  • 1
    @user2047861 What class is in vendor directory? I would not suggest to put your custom classes and modules in the vendor folder. – Wilt Sep 16 '15 at 16:02
  • I named my custom class `class StandartFuncs`. It located in `/vendor/Tools/src/Tools/Model/StandartFuncs.php`. And I also need access to global config variables in `vendor/zendframework/zendframework/library/Zend/Authentication/Adapter/DbTable/CredentialTreatmentAdapter.php`. I want to make select from another database in authenticateCreateSelect() which name is set in global configs. But there I face the same problem. – user2047861 Sep 17 '15 at 07:00
0

I don't think you've quite understood the solution you're trying to implement. The factory you're adding to the service config needs to return an instance of your library class. The reason you're putting it in a factory is so that you can inject the config array into it. So your code should look more like this:

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'funcservice' =>  function(\Zend\ServiceManager\ServiceLocatorInterface $sm) {
                $config = $sm->get('config');

                return new \SomeLibrary($config);
            }
        )
    );
}

(where SomeLibrary is the name of your library class in /vendor).

You will then need to use the service manager to instantiate your library class whenever you need to access it, e.g. in a controller:

public function someAction()
{
    $yourLibrary = $this->getServiceLocator()->get('funcservice');
}

This will create an instance of your library class, passing the config array as the constructor to the first parameter. You should never need to call getServiceConfig() yourself, and this wouldn't achieve anything.

Tim Fountain
  • 33,093
  • 5
  • 41
  • 69
  • Thank you for reply. In application controlers I access my library by `new \Tools\Model\StandartFuncs;`. So inside class function `getServiceConfig()` I replaced your `return new \SomeLibrary($config)` to `return new \Tools\Model\StandartFuncs`. Now statement `$this->getServiceLocator()->get('funcservice');` inside that class `public function save()` produces `Fatal error: Call to a member function get() on a non-object` – user2047861 Sep 16 '15 at 15:33
  • "inside that class xxx produces " - inside what class? The example in my answer showed you how you'd get an instance of your library class from a controller. What class are you trying to call it from? – Tim Fountain Sep 16 '15 at 15:59
  • My custom class is located in `/vendor/Tools/src/Tools/Model/StandartFuncs.php`. I named it StandartFuncs. Now it has `public function getServiceConfig()` too. I use this class in `/module` controllers as `$funcs = new \Tools\Model\StandartFuncs;`. It works fine until I need global config variables in it. – user2047861 Sep 17 '15 at 07:13
  • Like I said, you will need to use the service manager to instantiate your class so ZF can inject the config into it. So do `$funcs = $this->getServiceLocator()->get('funcservice');` instead of `$funcs = new \Tools\Model\StandartFuncs;`. I'm not sure why you have a get service config function in your class - that probably shouldn't be there. – Tim Fountain Sep 17 '15 at 10:48