I defined an alias for MyClass that I want to be retrievable via ServiceManager, see module.config.php example below. When I retrieve an instance of MyClass in my controller via $this->serviceLocator->get('MyClass') I get a new instane the first time, and then the same instance. Do I miss something in my configuration or should I file a bug?
module.config.php
return array(
'di' => array(
'instance' => array(
'alias' => array(
'MyClass' => 'Some\Namespace\MyClass',
),
'MyClass' => array(
'shared' => false,
),
),
),
);
As my edit was not accepted, I will answer this question myself. In the end I moved to ServiceManager thanks to Stoyan Dimov who pushed me into the right direction. Unfortunately his answer was not correct. I had to use invokables instead of alias. Here is the correct example:
return array(
'invokables' => array(
'MyClass' => 'Some\Namespace\MyClass',
),
'shared' => array(
'MyClass' => false,
),
);
When I was using alias instead of invokables I got an exception that no service with that name can be is available, which means that aliasdoes not work, there has to be an existing service defined by invokables, factories, services or abstract_factories.
Following the previous example I could use:
...
'alias' => array(
'SomethingDifferent' => 'MyClass',
),
...
With a call to $this->serviceLocator->get('SomethingDifferent')I would receive an instance of Some\Namespace\MyClass.
I don't know about the DI but the ServiceManager expects your to specify shared (false) in the root of the configuration array for the manager. Something like this:
'invokables' => array( // Note that you can use also 'factories', 'abstract_factories', etc.
'Some\Namespace\MyClass' => 'Some\Namespace\MyClass',
),
'alias' => array(
'MyClass' => 'Some\Namespace\MyClass',
),
'shared' => array(
'MyClass' => false,
),
See the ServiceManager example configuration on the manual
Hope this helps :)
Stoyan
Related
Is it possible to get a new instance of a ZF2 View Helper, Form and the like on each call?
My main issue at the moment is with view helpers. Each time I call the helper I need it to be constructed as need to have new objects passed into it but it doesn't matter what config I have it only ever passes through the factory the once.
With that the objects which are generated via the factory are the same for each instance, which Is not what I'm wanting.
I've tried various configs such as setting the view helper as shared, but that hasn't helped.
This is my config as it currently stands;
/**
*
*/
'view_helpers' => array(
'shared' => array(
'notes' => false,
),
'factories' => array(
'notes' => __NAMESPACE__ . '\Factory\ViewHelper\Notes',
'note' => __NAMESPACE__ . '\Factory\ViewHelper\Note',
)
),
Any help would be great!
You're almost there.
The shared config key is to mark the services that require a new instance to be created each time you request them.
The problem however, is that you have to use the service name.
'view_helpers' => [
'shared' => [
'notes' => false,
],
'factories' => [
'notes' => __NAMESPACE__ . '\Factory\ViewHelper\Notes',
],
],
All I want to show there is available via ViewHelpers provided by the module.
Ok, I found a solution. I wanted to avoid the creation of a "dummy" Collector, because - as mentioned in the question, all I want to be visible on the toolbar, is available through provided view helpers.
Now I'm just pointing the Collector, to a collector that was already registered by the ZendDeveloperTools module (ZendDeveloperTools\RequestCollector):
return array(
'zenddevelopertools' => array(
'profiler' => array(
'collectors' => array(
'MyCollecor' => 'ZendDeveloperTools\RequestCollector'
),
),
'toolbar' => array(
'entries' => array(
'MyCollecor' => 'zend-developer-tools/toolbar/websafe-zf-mod-language',
),
),
),
);
I hope that's OK.
I'm building an app using Zend Framework v2.2.0 and I'm creating different modules for each section.
In a module, called Company, there is this route:
'company_wines' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:slug_company/:action/',
'constraints'=>array(
':slug_company'=>'[a-zA-Z0-9\-_]+',
':action'=>'(wines|red\-wines|white\-wines|sparkling\-wines|dessert\-wines|rose\-wines){1}',
),
'defaults' => array(
'controller' => 'Company\Controller\Company',
),
),
),
In another module, called Vineyard, I have this route:
'vineyard_page' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/vineyard/:slug_vineyard/',
'constraints'=>array(
':slug_vineyard'=>'[a-zA-Z0-9\-_]+',
),
'defaults' => array(
'controller' => 'Vineyard\Controller\Vineyard',
'action' => 'vineyard',
),
),
),
When I test with url domain.ext/Company-name/red-wines/ or domain.ext/Company-name/white-wines etc, the Company controller is invoked.
If I test with domain.ext/vineyard/Vineyard-name/, the Vineyard controller is not invoked, is still invoked the Company one and the error message say that the controller cannot dispatch the request. Off course there is no method called VineyardnameAction() in CompanyController class.
I was expecting that the route match against the list of values specified on regex for :action, also if the :slug_company regex match the "flag" vineyard, then there is no action that match the Vineyard-name part...
If I test the :action regex with preg_match_all, nothing is found in a string like domain.ext/vineyard/Vineyard-name/.
If I disable Company module or delete the the company_wines route, vineyard route is working.
I've solved creating different routes for each wines types, but I would like to understand whath I'm doing wrong :)
Your syntax is wrong:
'constraints' => array(
'slug_vineyard'=>'[a-zA-Z0-9\-_]+',
),
'constraints'=>array(
'slug_company'=>'[a-zA-Z0-9\-_]+',
'action'=>'(wines|red\-wines|white\-wines|sparkling\-wines|dessert\-wines|rose\-wines){1}',
),
remove the colon from the default / constraints section and it should work fine.
As you have put the colon in there the constraints aren't being forced so default constraints will be used, which ever route comes first will match.
I want to write routes for this type of urls
http://www.example.com/category/sub-category/id.html
here category is dynamic. means- i have 100 of categories in my db.
sub category is also dynamic.
i need to show page based on id value.
Any one please suggest.
Try reading the docs first its very simple :
'sample' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:category[/:sub_category[/:id]].html',
'defaults' => array(
'controller' => 'Your Controller',
'action' => 'Your Action',
),
),
),
With this router config you can have :
http://www.example.com/category.html
http://www.example.com/category/sub-category.html
http://www.example.com/category/sub-category/id.html
I am looking for a way to add translations to my ZF2 application, using globals in my URL.
Is there anyway to do this for the whole application at once?
A typpical URL would look like this: http://domain.com/en_GB/user/index
The first part (en_GB) should be used to show the correct translation.
Besides that, it would be nice, if it is possible to set this router part optional.
So, if I should go to http://domain.com/user/index (without the locale part) to my application, it should automatically take the browser locale.
I hope I am clear enough, if any additions are needed to this question, feel free to ask.
Thanx in advance
#DrBeza,
Thank you for your answer. I don't know if this is the correct way, but I created the next solution:
in /config/global.php I added this part
'translator' => array(
'locale' => 'nl_NL',
'translation_file_patterns' => array(
array(
'type' => 'phpArray',
'base_dir' => __DIR__ . '/../../language',
'pattern' => '%s.php',
),
),
),
in /module/[modulename]/config/module.config.php I added this part to set the first part of the URL containing the locale
'router' => array(
'routes' => array(
'user' => array(
'options' => array(
'route' => '[/:lang]/user[/:action][/:id]',
'constraints' => array(
'lang' => '([a-z]{2})+(_)+([A-Z]{2})',
),
),
),
),
),
in /config/local.php I added this code to fetch the locale from the URL:
http://domain.com/[locale][module][controller]
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segment = explode('/', $_SERVER['REQUEST_URI_PATH']);
And I added this part to load the locale dynamicly:
return array(
'translator' => array(
'locale' => $segment[1],
);
I would suggest extending the Segment route class and adding in the optional locale constraint and segment part if missing. Call the optional variable something application wide such as 'locale'.
Then create a 'route' event in the main module bootstrap, this event will fire once a route has been matched. The callback function that is fired will have access to the RouteMatch object through the passed event, letting you gain access to the 'locale' value. Then you can do some checks and set the application locale.