ZF2 global config settings - php

My goal is to have configuration settings shared and editable within each module in a Zend Framework 2 project. After research, I came to this: http://akrabat.com/zend-framework-2/injecting-configuration-into-a-zf2-controller/ which worked great at first but after my application keeps expanding to more modules and more controllers, I don't appreciate this solution. Precisely, I don't appreciate having to "implement" interface, add SetConfig method and so on. Instead, I'd like to be able to just call on $GLOBALS or similar in my controller and get the parameter of interest.
Say I have a file config.local.php with the following format:
return array(
'group1' => array(
'key1' => 'value1',
'key2' => 'value2',
)
'group2' => array (
'subgroup' => array (
'keyA' => 'valueA',
'keyB' => 'valueB',
),
)
);
Right now, i'm following the tutorial above and after implemeting the ConfigAwareInterface in my controller, I get valueA using
$this->config['group2']['subgroup']['keyA']
I'm now hoping to just rather call $GLOBALS['group2']['subgroup']['keyA'] without the ConfigAwareInterface intermediate.
I laid the following quick pseudo code to help me achieve that:
for every this->config as key => value
if $key is not array
$GLOBALS[$key] => $value
else
for every $value as $k => $v
$GLOBALS[$key][$k] => $value
As ZF2 and php are new to me, I'm not completely sure I can have more than 1 index/nested keys for $GLOBALS but I can tailor my config file to avoid that.
There are probably other logical mistakes above. But just to get the point. Now, is this the best way to go about global configuration or is there a better approach?
Thanks in advance.

You can always easily access the configuration via:
$this->getServiceLocator()->get('config');
What Akrabat did was to provide a shortHand getConfig()-

Related

Best practices for read array from file in Laravel

My question might be stupid. But i need to clear my concept about it.
There are several ways to read array in Laravel. like config() variable , .env function, trans() function, file read like .csv, .txt, .json etc.
May be all of them are different purpose.
But i need to know what will be the good practice to read array data from my controller. An example given. Thanks
Example array:
[
"mohammad" => [
"physics" => 35,
"maths" => 30,
"chemistry" => 39
],
"qadir" => [
"physics" => 30,
"maths" => 32,
"chemistry" => 29
],
"zara" => [
"physics" => 31,
"maths" => 22,
"chemistry" => 39
]
]
Laravel uses var_export() under the hood to cache the config in this way:
$config = [
'myvalue' => 123,
'mysub' => [
'mysubvalue' => true
]
];
$code = '<?php return '.var_export($config, true).';'.PHP_EOL;
where $config can be a multidimensional associative array.
if you put that string into a file:
file_put_contents(config_path('myconf.php'), $code);
in the code you have to simply include that file to have your structure
$myconfig = require config_path('myconf.php');
dd($myconfig);
or (if is config file) call
echo config('myconf.myvalue');
To retrive values in Laravel style you can use the Illuminate\Config\Repository class
eg.
$conf = new Illuminate\Config\Repository($myconfig);
echo $conf->get('mysub.mysubvalue');
or
echo Illuminate\Support\Arr::get($myconfig, 'mysub.mysubvalue');
hope this will clarify and help
I don't know if this is best practice, but i can sure you that it's working, not just in Laravel but in any other PHP project.
That been said, to read an array from a file all you have to do is to include this file, the returned array you can assign it to a variable.
The array must be returned form the included file, it's important
Example:
path/to/my/array_file.php
<?php
return [
'resource' => [
'delete' => 'Are you sure you want to delete this resource?',
'updated' => 'Data for this resource has been successfully updated',
'created' => 'Data for this resource has been successfully created',
'deleted' => 'Data for this resource has been successfully deleted',
],
];
If i need to access this array any where in my project, i can include it like this:
$messages = include('path/to/my/array_file.php');
Now $messages is just another php array.
if you var_dump($messages) or dd($messages) in Laravel you get something like this:
array:2 [▼
"resource" => array:4 [▼
"delete" => "Are you sure you want to delete this resource?"
"updated" => "Data for this resource has been successfully updated"
"created" => "Data for this resource has been successfully created"
"deleted" => "Data for this resource has been successfully deleted"
]
]
Just a minor correction to the answer above: the author asked about reading the data, so they presumably need unserialize(file_get_contents('data.file')); However, I do support the answer above as it's really bad idea to store and read something from the filesystem, not only because of concurrent read/writes , but because of speed/file access/caching issues as well.
There are serialize() and unserialize() functions that creates/loads a textual representation of any php value.
However, I would use files for storing data ONLY if the data do not change much on runtime. E.g. for caching or configuration purposes. Otherwise, you may run into collisions when multiple sessions attempt to read/write the file at the same time and produce weird errors
http://php.net/manual/en/function.serialize.php
Responses to some of the comments by OP:
Laravel uses config files that are interpreted, i.e. parsed by the PHP once the framework boots up. Use of such files enable the use of some neat language features, such as class injection, allows to version the config files, and makes life somewhat easier for devs as the config pertaining framework stuff is stored in the code.
For runtime, session-specific stuff, use a database. There is $_SESSION[] variable for storing temporary data. Depending on your config the values could be stored in memory or files, and the PHP takes care of them.
I wanted to import a simple array from a file in a Laravel project . I saved the file in resources/appData and for loading the array I ended up in this:
$categories = include(resource_path('appData/categories.php'));
This will load the array from the file located in 'resources/appData/categories.php' and save it to the $categories variable.
The file returns an array like the config files in Laravel
<?php
return [
];
I don't know if this is a best practice though.

Cakephp need session var in model

I give. Been searching and trying different stuff for hours.
Using Cakephp 2.3.5.
I'll get straight to it.
I want to use a session variable in my Category model, but it doesn't like it when I try any of the following...
$this->Session->read('market_id')
CakeSession::read('market_id')
SessionHelper::read('market_id')
Here is the model snippet where I'm trying to use it...
public $hasAndBelongsToMany = array(
'Vendor' => array(
'className' => 'Vendor',
'joinTable' => 'categories_vendors',
'foreignKey' => 'category_id',
'associationForeignKey' => 'vendor_id',
'unique' => 'keepExisting',
'conditions' => array( 'market_id' => ???? )
)
);
I'm stuck like a wheelbarrow in the mud. I've read countless opinions of why I shouldn't use session data in the model, but this makes perfect sense to me since it will never be called without this value set, and it should never return anything other than the vendors with that market_id. But that value does change.
I'm completely guilty of doing everything I can to avoid messing with my models. The whole skinny controller idea... yea... nice thought, but I just haven't figured it out yet. And so it goes. The first time I try to modify a model... I can't figure out how.
I've read countless opinions of why I shouldn't use session data in the model
That's correct. It will cause tight coupling as well and make it harder to test. And it's not only valid for models but everything. Don't create tight coupled code.
It is better to pass data and objects around. For example:
// Model Method
public function getSomething($someSessionValue) { /*...*/ }
// Controller
$this->SomeModel->getSomething($this->Session->read('something'));
If you need your data in a lot methods you can set it:
public function setSomeModelProperty($value) {
$this->_someProperty = value; // _ because it should be protected, the _ is the convention for that in CakePHP
}
However, I personally would very like go for passing the data to each method. But it depends on the whole scenario.
And you can't do this any way because it will cause a syntax error. You can't use variables or properties in the property declaration.
'conditions' => array( 'market_id' => ???? )
So bind it later by a method like
public function bindVendors($marketId) {
$this->bindModel(/*...*/);
}
when needed.
Or even better, simply use the conditions only when needed and declare them in your find options:
[
'contain' => [
'Vendor' => [
'conditions' => /* conditions here */
]
]
]

What does PURE CONFIGURATION mean in ZF2?

I was going through Form Creation in ZF2 and I read the following statement.
"
You can create the entire form, and input filter, using the Factory. This is particularly nice if you want to store your forms as pure configuration; you can simply pass the configuration to the factory and be done."
Can anybody tell in detail what does PURE CONFIGURATION mean?
It means that you're able to store your forms within any config file, e.g. module.config.php and then pass this configuration key into the form factory. This is similar what has been done in ZF1 often times, too.
This whole process is done through the Zend\Form\Factory and if you check out the source code you'll see that you could pass it the following array to create a Form
$someConfig = array(
'form-key-name' => array(
'fieldsets' => array(
'fieldset_1' => array(
'elements' => array(
'elem_x' => array(/** Single Form-Element Array*/)
),
'fieldsets' => array(
'fs_y' => array(/** More Sub-Fieldset Array*/)
),
)
)
)
);
Note that this example is quite incomplete (missing name => foo), hydrator configuration, inputFilter configuration, etc... but as it is this should give you a idea of what's meant by that statement.
Using the above-mentioned configuration then you can pass it to the factory
$factory = new \Zend\Form\Factory();
$form = $factory->createForm($someConfig['form-key-name']);

ZF2 Zend_Translate content to get search completion

i'm searching for a solution to solve the following problem in zf2:
i have a list of destinations, and i want a search-formular on my page with auto-completion.
also the list is used to translate parts of my web-page, so i will use zend_translate to do this.
it it possible to "reverse-search" the list of translations with zend_translate?
Example:
$translate->getKeysByExpression('*ger*');
result:
array (
array ( 'key' => '__germany__', 'name' => 'germany'),
array ( 'key' => '__trn_landwithger__', 'name' => 'landwithger'
)
it is not the biggest problem if i have to load the complete list of translations, it is not that much.
or is it better to use mongodb as backend for zend_translate, and use direct queries to find the completion-candidates?

Zend_Form_Element_Select default value

In my form, I want to set the selected (default) value for a select element. However, using setDefaults is not working for me.
Here is my code:
$gender = new Zend_Form_Element_Select('sltGender');
$gender->setMultiOptions(array(
-1 => 'Gender',
0 => 'Female',
1 => 'Male'
))
->addValidator(new Zend_Validate_Int(), false)
->addValidator(new Zend_Validate_GreaterThan(-1), false);
$this->setDefaults(array(
'sltGender' => 0
));
$this->addElement($gender);
My controller is simply assigning the form to a view variable which just displays the form.
It works by using $gender->setValue(0), but it would be easier to set them all at once with an array of default values. Am I misunderstanding something here?
Also, where is the Zend Framework documentation for classes and methods? I am looking for something similar to the Java documentation. The best I could find is this one, but I don't like it - especially because every time I try to search, it crashes.
Have you tried:
$this->addElement($gender);
$this->setDefaults(array(
'sltGender' => 0
));
Also, take a look at http://framework.zend.com/issues/browse/ZF-12021 .
As you can see, the above issue is similar to the issue you're describing. It seems Zend is very particular about the order you create objects and assign settings.
I'm afraid you're going to have to do things in the order Zend wants you to do them (which doesn't seem well documented, but is only discovered thru trial and error), or hack their library to make it do what you want it to do.

Categories