I am working on code re-factoring of configuration file loading part in PHP. Earlier I was using multiple 'ini' files but now I plan to go for single XML file which will be containing all configuration details of the project. Problem is, if somebody wants configuration file in ini or DB or anything else and not the default one (in this case XML), my code should handle that part.
If somebody wants to go for other configuration option like ini, he will have to create ini file similar to my XML configuration file and my configuration manager should take care everything like parsing, storing in cache. For that I need a mechanism lets say proper interface for my configuration data where the underlying data store can be anything( XML, DB, ini etc) also I don't want it to be dependent on these underlying store and anytime in future this should be extensible to other file formats.
Assuming you're wanting to use a class to handle all this, you have 3 options:
Have a base class called something like, ReadConfigurationBase then 3 implementation classes, ReadConfigurationXML, ReadConfigurationINI, and ReadConfigurationDatabase and you'd have to choose the right one
Same as above, but using a factory to choose, based off of something passed in. Like if you pass config.xml it would know to return ReadConfigurationBase implemented using ReadConfigurationXML
Have a class called ReadConfiguration and it acts as step 2, but creates, contains, and owns, the 3 other classes.
The 3 non-base classes would simply know how to read that type of configuration file, and pass the information back in a generic manner. think along the lines of an interface: You know you can get the data, but you don't care how.
I'd suggest option 3, since it would make life easiest. You would have to do a little bit of modification every time you want to add a storage method, but that would just be adding a little bit into the ReadConfiguration class.
There is a way you could make it 100% dynamic, but that would complicate matters, and I don't think you really need it for this.
Have a look at Zend_Config. It provides adapters for Arrays, Xml and Inis. Like all components in Zend Framework, it can be used isolated from the remaining Framework. Even if you don't want to use it, it's well designed and you might get a few ideas for your own config manager from it.
Related
In Zend Framework 2 I wrote a module with custom configuration options.
The options are obtained using the service locator and are then passed to the object that is being initialized inside a factory.
Since my configuration is in PHP array format, I could just pass the array, or I could first create a new instance of Zend\Config\Config and pass this to the new object.
I tried both ways & they both work, but what is the recommended way of doing this inside ZF2 & why? Does it has any advantages to use Zend\Config\Config?
Especially since I just noted it's possible to cast the Config back to an array using toArray() I am curious of possible benefits.
By using the object you would be keeping with the OOP inherent to Zend, plus it has functionality not available to a basic array, and it can be extended to use custom business logic if the need arises.
IE, maybe a condition comes up that will change one of the configuration options, but the rest are the same.
If I'm developing a project for others, I like to give them a certain level of access to the configuration so that they do not have any reason to delve into the code themselves. I'll create a table in the database called something like 'settings' or 'config' that the admin can access through a form, and the data populates a php configuration array. In order to do this, the PHP array format is the way to go.
("a" recommendation, not necessarily "the" recommended way)
Most of the modules just add to the global config, that is accessible via $serviceManager->get('config')
This way your config can be cached later on via config_cache_enabled in application.config.php and users can override config options using their local configurations.
If your's module config isn't related to the global config mechanism it's really up to you on how you store/manage it. Keeping it as an array is simpler, whereas using it as Zend\Config\Config lets you use various tools for config (ini writers, database etc).
I have a set of shipping codes that I want to be able to store in our database. I will be adding to this list in the future, so ideally I'd like to have them in a YML fie that I can just add to. I want to be able to run a task that will populate the DB with the YML data, and will update a record if it notices something has changed. Is there any tool out there in PHP that already does this for me?
Hava a look at Zend_Config, it provides Readers and Writers for YAML, XML, JSON and INI. As for the updating task... you'll have to do that on your own because your database structure is unknown to any existent tool.
I'd advise you to take a look at http://www.symfony-project.org/api/1_4/sfYaml. I've used this class separated from the whole Symfony framework and I worked great for me.
There are many options for you;
http://php.net/manual/en/book.yaml.php
http://pecl.php.net/package/yaml
http://code.google.com/p/spyc/
And: PHP YAML Parsers
So I have a large class that I'm refactoring to be more flexible.
well over 100 configurable properties (variables) in a INI file. Some are dev settings and others are production settings.
Currently I use a environment flag to pull the INI settings I need (either dev or prod).
All the INI fields are mandatory and must be set. (currently using setters for this).
So what makes more sense?
A: to keep the current setup
B: Move to another type of configuration setup (like xml or something)
C: Move all settings into the script itself and remove the INI parsing and validation code (setters)
D: suggestions?
Bonus question:
I was reading this over the weekend: http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/ and wanted to know how I could follow more of this type of development style but confused as how to not use getter/setter functionality with setting mandatory fields? I understand the need to getters/setters and wanted to know if I'm implementing them correctly?
I use the INI for stuff like DB settings, validation limits (think spending limit of $100 but could change), large array (static values like the 50 US States but with the ability to add US territories as well)
If you want to keep settings
readable, keep the current setup or
move settings into PHP script (but do
not hardcode them into classes).
If
you want to increase performance -
use JSON format or PHP script -
json_decode works faster, PHP script
works faster and can be easily cached
by APC.
As variant, you can parse
the settings file once and put all
settings in cache (APC or memcache).
Also. I think nobody cares, but I have my opinion about getters and setters :)
Getters and Setters aren't evil. Idea of Encapsulation is not just hide fields, but hide, how class works. Getters and setters can be declared in interface, so you can replace one object by another - and it is what for encapsulation was invented!
Let's take example from article of Berry Langerak - withdraw and deposit it's setters. All this code can be successfully done in setBalance method, almost nothing will be changed. All these checks, comparison - it's usual work of setters.
Why public fields are evil? Because object can't control their changing and because they can't be declared in interfaces. Getters and setters can do it, so it's perfect tool of OOP.
Accessors can be written silly, of course, but it doesn't mean that they are evil. Any method in the class can be written silly.
Interesting question.
I highly doubt that all of those variables are/could be different between your development area and your production area. Not every variable that you might change when debugged would have to be stored inside a config file.
I would advice using constants for the most variables.
You have auto complete, tons of IDE options and it's easily editable. Not to mention it's more logic to split them up into different files then to parse tons of ini's.
I'm trying to implement url routes into my own mvc framework and I like to find out the best way to do it. I'm thinking three solutions.
Make a XML file and read it in my frontend controller then load the matching controller.
Make a table that stores routes then execute a query in my frontend controller then load the matching controller.
use either xml or table and then load routes into memcache then use it.
my concern for #1 and #2 is that I have to read a table or xml for the every access.
my concern for #3 is that not all the hosting companies support memcache.
Any suggestions would be appreciated!
Added: I think I confused some people. By 'route', I'm actually talking about rewriting...like...I want to rewrite visitors to '/controller/action' when they visit '/hello'
Thanks
I would not use XML or tables for this. This will require additional resources for such (in comparison) easy operation. You should have a script which is loaded by mod_rewrite, it parses the URL, loads the proper controller and executes the action.
Hey I know this is a little late, but please check out my Routes class. I know you may not need it now, but hopefully it will still be useful to others.
With this you could easily do exactly what you need to with simple syntax and rules. All you need is to break down the parts of the returned URL (from a Routes::route() call) to calculate your controller and action method (and any possible parameters).
The reason this routing library doesn't do that for you is because you may not be in an MVC world when using it, but it's not that difficult to create. Because it's so low-level you could even create routes dynamically, say from a database table or memcache.
I think I can re-phase and even generalize the problem:
You want to create a representation for something (in this case URL
routes) that are easily human readable (eg, XML);
You might also like that this representation can be easily
computer-generated (eg, from a database table);
At run-time you don't want the solution to be slow: eg, parsing a
large XML file, reading from disk, or fetching rows from a database.
You don't know what caching solution will be available in a
production environment.
So you should aim to:
Perform the slow operations (reading from a database, parsing XML) as
little as possible - perhaps in a compile or build phase, or "on
first run".
Perform the route matching in a fast way: compile the rules directly
into PHP code, and execute them as regular expressions or some such.
Cache the rule code as a php file and include it as regular code. APC
is a php code cache that is commonly available in all production
environments.
This would lead me to implement a solution with the following classes and methods:
Router::addRoute(pattern, controller) - adds a route
Router::match(uri) - returns matching controller
You can store routes in whatever format you fancy (XML, Json, in a database), and generate a simple PHP include file to load routes quickly at runtime:
<?php
// compiled_routes.php
$router = new Router();
$router->addRoute('/', 'HomeController');
$router->addRoute('/widgets', 'WidgetsController');
tl;dr: separate the route rule-parsing from the route matching. Perform rule-parsing only once, and compile the result into PHP code which can be cached by APC.
Hope that helps.
What I really like about Entity framework is its drag and drop way of making up the whole model layer of your application. You select the tables, it joins them and you're done. If you update the database scheda, right click -> update and you're done again.
This seems to me miles ahead the competiting ORMs, like the mess of XML (n)Hibernate requires or the hard-to-update Django Models.
Without concentrating on the fact that maybe sometimes more control over the mapping process may be good, are there similar one-click (or one-command) solutions for other (mainly open source like python or php) programming languages or frameworks?
Thanks
SQLAlchemy database reflection gets you half way there. You'll still have to declare your classes and relations between them. Actually you could easily autogenerate the classes too, but you'll still need to name the relations somehow so you might as well declare the classes manually.
The code to setup your database would look something like this:
from sqlalchemy import create_engine, MetaData
from sqlalchemy.ext.declarative import declarative_base
metadata = MetaData(create_engine(database_url), reflect=True)
Base = declarative_base(metadata)
class Order(Base):
__table__ = metadata.tables['orders']
class OrderLine(Base):
__table__ = metadata.tables['orderlines']
order = relation(Order, backref='lines')
In production code, you'd probably want to cache the reflected database metadata somehow. Like for instance pickle it to a file:
from cPickle import dump, load
import os
if os.path.exists('metadata.cache'):
metadata = load(open('metadata.cache'))
metadata.bind = create_engine(database_url)
else:
metadata = MetaData(create_engine(database_url), reflect=True)
dump(metadata, open('metadata.cache', 'w'))
I do not like “drag and drop” create of data access code.
At first sight it seems easy, but then you make a change to the database and have to update the data access code. This is where it becomes hard, as you often have to redo what you have done before, or hand edit the code the drag/drop designer created. Often when you make a change to one field mapping with a drag/drop designer, the output file has unrelated lines changes, so you can not use your source code control system to confirm you have make the intended change (and not change anything else).
However having to create/edit xml configuring files is not nice every time you refractor your code or change your database schema you have to update the mapping file. It is also very hard to get started with mapping files and tracking down what looks like simple problem can take ages.
There are two other options:
Use a code generator like CodeSmith that comes with templates for many ORM systems. When (not if) you need to customize the output you can edit the template, but the simple case are taken care of for you. That ways you just rerun the code generator every time you change the database schema and get a repeatable result.
And/or use fluent interface (e.g Fluent NHibernate) to configure your ORM system, this avoids the need to the Xml config file and in most cases you can use naming conventions to link fields to columns etc. This will be harder to start with then a drag/drop designer but will pay of in the long term if you do match refactoring of the code or database.
Another option is to use a model that you generate both your database and code from. The “model” is your source code and is kept under version control. This is called “Model Driven Development” and can be great if you have lots of classes that have simpler patterns, as you only need to create the template for each pattern once.
I have heard iBattis is good. A few companies fall back to iBattis when their programmer teams are not capable of understanding Hibernate (time issue).
Personally, I still like Linq2Sql. Yes, the first time someone needs to delete and redrag over a table seems like too much work, but it really is not. And the time that it doesn't update your class code when you save is really a pain, but you simply control-a your tables and drag them over again. Total remakes are very quick and painless. The classes it creates are extremely simple. You can even create multiple table entities if you like with SPs for CRUD.
Linking SPs to CRUD is similar to EF: You simply setup your SP with the same parameters as your table, then drag it over your table, and poof, it matches the data types.
A lot of people go out of their way to take IQueryable away from the repository, but you can limit what you link in linq2Sql, so IQueryable is not too bad.
Come to think of it, I wonder if there is a way to restrict the relations (and foreign keys).