How is it possible to provide global information (paths, DB passwords, Timezone, ...) in a PHP Application? I know, that global variables are unsafe, but how do common CMS handle this problem? I already looked at Wordpress, but WP isn't famous for it's high security standards.
I've read a little bit about Dependency Injection, but is this the common way to handle this?
All in all I want to provide a type of global (but controlled*) information.
*Is it possible to control the provided data in a way that only authorized objects get the required information?
You can use configuration files (.ini), it's easy to use with this PHP function parse_ini_file.
You can use it like that :
config.ini
[global-information]
path : your_path
DB_passwords : your_password
Timezone : your_timezone
In your php file you can get global information like that
$ini_array= parse_ini_file("config.ini",true);
$path = $ini_array['global-information']['path'];
Dependency injection has nothing to do with security. It is a design pattern, a strategy to solve a common problem in a well-structure way.
I typically prepare a class CSettings, which provides method for all types of information, but all in a generic way by means of methods.
Then, when used in a specific application, I subclass CSettings in such a way, that it returns the correct / concrete values for the specific application.
Another way to promote information, could be e.g. the registry pattern.
There are many schools of thought on this. The most basic implementation is probably a global configuration file that sets constants using define()
I once worked with a framework that used this method extensively, coupled with singletons for Database Access and domain settings. It is still widely used, but generally deeper dependency injection, where definitions for configuration are made class specific is now considered more modern and reusable, since the single package contains all the definitions to make it work in the same file.
http://misko.hevery.com/2009/01/14/when-to-use-dependency-injection/
This is a great article about the finer points of dependency injection. The key thing to remember is that objects should only instantiate or hand off other objects if they are directly needed within the current scope. The author gets in to great detail.
There are also alot of more famous libraries like HTMLPurifier that use a configuration object that gets handed to the constructor of the object instance when it is created. This is a good approach if your object has highly complicated and nested config.
Related
With a PHP MVC project, I have a few model classes that load data from a RESTful web service, which requires an API key. I'd like to store the necessary API key in the central config file of my application.
To get that API key to my class, which method would be considered best?
Put the value in $GLOBALS, so it can be accessed directly within the model classes which utilize it.
Pass the value to the class upon instantiation.
Method #2 seems best for OOP and code reuse, but method #1 is very convenient. I typically go with method #2, but I want to know if method #1 is generally considered to be an acceptable use of $GLOBALS, even in an OOP MVC environment.
Symfony 1.4 uses an sfConfig::get('my_value'), which is like your first option, only wrapped in an object.
Symfony 2 uses dependency injection to reduce coupling, which is like your second option. Make sure you check out this link for a good explanation on dependency injection.
However, reducing coupling increases complexity. So, it's really a tradeoff. I think the main point is to be consistent in your application. Whichever method is used can be changed, so long as you're consistent in its use.
I would pick dependency injection. Not only is it easy to use if you use it all of the time, it's much more likely to lead to reusable code. The slowest part of a computer is the developer, so I try to build high quality, reusable components, wherever possible. I should also note that using dependency injection makes it much, much easier to build unit tests, should you choose to increase the quality and consistency of your code by adding unit tests.
Hope that helps...
I 'd say the best here would be a third option: use a global constant.
define('API_KEY', 'foobar');
This is reasonable in the sense that the value of this constant is practically going to be unchanged during the lifetime of your application. A constant is better in that case because the value cannot be modified or overwritten through accident or malice. Plus, it does let you keep the convenience of a globally available value.
You could also use class constants and/or statics:
class myClass
{
const MY_API_KEY = 'somestringofstuff';
// Or use a static array if you need access to multiple keys
public static $apiKeys = array(
'dev' => 'mydevapikey',
'prod' => 'myprodapikey'
);
}
// Calling code
$apiKey = myClass::MY_API_KEY;
// Or
$apiKey = myClass::$apiKeys['dev'];
Why should I use Zend_Registry instead of the Singleton pattern?
My coworker and me recently had a discussion about this. His point was that we should use Zend_Registry for all consistent objects, but I wanted to use the singleton pattern, since Zend_Registry just does the same, but wrapped.
I have a problem with code like this:
$list = Zend_Registry::get('database')->getList($sql);
Since theres a chance that database isn't in Zend_Registry. In cases of lazy loading, I would have to make my own registry with information about specific objects in my system. Like if the database takes specific parameters on loadtime, then it would have to know this.
I would instead use getInstance and then all the code would reside in the same object. Does that make sense?
Even though you phrased your question as an either/or, might I suggest a third alternative?
I try to avoid both singletons and Zend_Registry wherever possible, since they function, in effect, as globals. When a segment of code can reach into the global ether - via a call to a singleton or a global registry - to get something it needs, it creates a hidden - or at least, a non-explicit - dependency that makes things harder to debug and unit-test.
In contrast, I try to follow dependency injection advice, paraphrased as: "Give a component what it needs. Don't make it find what it needs."
I find that for most entities for which I might feel I need a registry/singleton - db connections, loggers, etc - I can create them at Bootstrap, store them in the Bootstrap registry and inject them into my controllers, usually during init() using $this->getInvokeArg('bootstrap')->getResource('myResource'). Only controllers reach back into the Bootstrap. Then, any models or services that need these dependencies get them passed-in explicitly by the controller, either via constructor or by setter injection.
A hybrid approach to which I do sometimes fall back is to design my service/model classes with getters/setters for these dependencies - getDbAdapter() and setDbAdapter(); getLogger() and setLogger(), etc. The getter lazy-loads from the global registry - whether some singleton or by Zend_Registry, throwing exceptions when they are not where I expect them to be. In that sense, it is similar to what you are suggesting. It does violate the purist dependency injection philosophy. But at least the presence of the getter/setter methods explicitly demonstrates that there is a dependency and allows me to mock it out or to provide non-default implementations.
It does for simple blog or something. Otherwise you're stuck with only one DB instance. And that's NOT what you want in the long run. You may want to connect to other server (to log errors to central db, to import products from someone, ...) or connect as different user (for security reasons - you don't want your API to have access to admin_users table, but you still need to connect to it to check if user is valid in the first place).
You can do one-purpose registers (My_Db_Admin, My_Db_ReadOnly, ...) but that does not make much sense to me. Using registry you're not stuck with one instance. You can create one outside registry and work with it for a while and then trash it ;)
I'll start by saying that I know how PHP interfaces work and how to "use" them.
My question is rather; how do they become useful in real life applications?
I've been writing PHP for over 3 years now and have never felt the need for an interface. I am writing interfaces more for good practice than for a particular purpose.
I'll provide an example where I've used interfaces in my own real-world experience.
Interfaces are extremely useful when you need to define something like a plugin architecture. Suppose your application accepts authentication plugins, allowing your end user implementers to integrate with their own internal auth infrastructures (LDAP, Shibboleth, some custom auth database, whatever). In order for a plugin to be compatible, it must implement the following methods:
validate_user()
start_user_session()
logout_user()
get_user_details()
If defined in an interface, a class then implements the interface ensuring that the necessary methods are present for compatibility with the plugin architecture.
Unfortunately, PHP does not enforce the return type of interface methods, so you must simply take care to document the expected return functionality of your methods.
They are not so useful - yet. Their main purpose seems to be for type hinting. When you write two separate classes that implement the same interface, you can use that interface in the type hint for a function. That way, you know you got all the methods of that interface available in the object that is passed in the parameter.
Unfortunately, PHP doesn't actually check if any called methods or properties you call on that parameter are actually in that interface, so you can accidentally use an object property that is not available in the interface, causing potential bugs when an object of a different type is passed.
Other languages are much stricter in this situation and will only allow you to use only that functionality that is declared in the interface.
Nevertheless, they are convenient for this purpose in PHP too, and maybe these checks will become stricter in future versions, so it becomes less error prone.
Check out the Standard PHP Library (SPL)
http://php.net/manual/en/book.spl.php
Countable and RecursiveIterator might give you a clue.
I've got this Config-class that I use in my PHP5 application to load & parse my static config. This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
But now as I need to set/make changes in my Config during runtime at one place, my changes aren't reflected globally and being far from a specialist with the use of the static modifier in PHP, I need to ask:
What is the best way to ensure that changes to the properties in my Config-class are reflected throughout my application without making the class into a singleton? Can I just make the variable holding the config data static?
This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
If you pass the same instance of your Config class to every part of your application and you change a setting it should be reflected everywhere else.
In case you are creating multiple objects of the class (and parse that config file every time?!) you might want to stop doing that. It's possibly wasteful and I'd say it is confusing.
So if you create only one and pass that around everything should be fine.
Under the assumption that you create multiple instances of the object that only should exist once:
If you are able to "fix" your architecture to allow you to do that: Do so.
If you can't to that... well.. creating a static property to hold your values in a class that you can have multiple instances off is, at least in my book, a major wtf factor. If you can't fix (meaning it's to much off a hassle to do so) just "break" it in an expected way so other people don't trip over it.
I'd rather have a singleton than something that creates all the issues with singletons and also lies about being a wrapper for a global variable.
Blindly avoiding design patterns because you hear on Internet forums that they're bad is about as much an anti-pattern as singletons are in general. If a tool is right for a job, then it's right.
Look at your question, you're trying to emulate singletons through a complex multi-update system for God's sakes... And just so you know, making a class static is essentially turning it into a singleton, albeit an insecure one that can be overwritten at any time.
TL;DR: Think for yourself and use the right tools; make your config class a singleton.
Before I begin, this framework is not meant to compete with Zend, Symfony, Cake or any other framework. It is primarily a personal project so that I may test out some PHP 5.3 goodies, experience new techniques and gives me the chance to try things under my idea. I am also trying to make this framework as lightweight as possible, and reduce the amount of unncessary getters and setters. Now for the problem at hand.
A bulk of the framework is done, primarily all the core classes required for it to run. The problem arises on the entry point of the application. I want the whole application to be run through a single core object which branches out. The core object will be extended with classes to manage environments, configuration, registry, autoloading, routing, etc, etc. You can see this "core" object below, it is aptly called Application.
https://github.com/titon/titon/blob/42c88e36c29e3d8c697306fe68be18b3a8fd2e70/titon/source/Infrastructure.php
$app = new \titon\source\core\Application();
The idea was that from anywhere in the application, you can access the core objects through this $app variable. Example:
(I cant post more than 1 link, so please go to the following directories on Github. /app/config/Setup.php and /app/modules/core/Bootstrap.php)
$app->environment->current();
$app->loader->includePath(array(__DIR__));
$app->registry->factory('titon\source\system\Controller');
But now we get into the problem of global variables, which I do not want to use. I also like to try and avoid Singletons.
public function foobar() {
global $app; // Eww
}
But I also do not want to use static classes, as I was trying to go for a more OOP approach. The only solutions I can think of is using a static class property to hold the Application instance and access that everywhere, but I do not like that. Or I can pass the object down to its children over and over again, but again, not a fan.
Core::$app->router->detect(); // Meh
$this->setApplication($this); // Mehher
I was curious how Zend and Symfony approached this problem. But after looking through their source code, I could not backwards engineer and determine the correct entry point. Furthermore, it seemed Zend would created global variables all over (Zend_Config, etc), but I would prefer to have a managing object. Symfony 2.0, I just got lost. As for Cake, Solar, Fuel, it seems they are using static classes for these kind of objects.
Now my primary question is, how would you solve this? I would like to keep a single object to instantiate and be accessible everywhere, but it doesn't seem like an easy thing to handle. I am willing to rewrite a lot of the framework if need be.
The idea was that from anywhere in the application, you can access the core objects through this $app variable. Example:
...
But now we get into the problem of global variables, which I do not want to use. I also like to try and avoid Singletons.
That seems like a contradiction to me.
Do you know why you don't want any global variables? Is it because you read somewhere that global variables are a bad thing?
Conversely, do you know why you want a central object that is available from anywhere in your application?
Follow Up:
In case it wasn't clear, those were meant as rhetorical questions. From an architectural viewpoint, global variables (in any shape) are expensive. Some say evil. I think that's missing the point slightly - You need some amount of global variables in any application (At least one). To further muddy the waters, "global" is really a relative thing; It is much more meaningful to consider variables as having varying scopes, where global is on one extreme of the continuum and local, temporary variable at the other. If you have a single object containing all your other objects, then I would consider each of these variables as being effectively global variables, even though they may not be so in a technical sense. Think a bit about that.
As for a silver bullet, you could take a look at dependency injection. This is an approach to avoiding global variables that works, but has some cost in the form of complexity.
One of PHP's old unresolved issues: One can't define superglobals, without using a extension like runkit.
I usually solve this with a pseudo-Registry, i.e. I define a class R with all variables I want to make global defined as public static $var. I know, this is probably not the vanilla-OOP approach, but it serves well. R::$var is as short as it get, I think. Everything else, like dependency injection ($this->var) or singleton (R::getVar()), is longer.
The best solution to avoid global variables is dependency injection. You'll probably need to create some container. Look at the Symfony components library.
You may also try registry pattern.