I'm a big fan of OOP in php, but i feel like defining class methods gets disorganized so fast. I have a pretty good background in OOP in C++, and i am pretty comfortable with how it is handled there, and am curious if there are ways to do it similarly in php.
To be more specific, here is what i mean. I like how in C++ you can define a class header (myclass.h) and then define the actual details of the functions in the implementation file (myclass.cc). Ive found that this can easily be replicated using interfaces in php, but i havent found a good solution for the following:
I like to organize my code in C++ in different files based on how they are accessed, so for example, public methods that can be called outside of the class would be in 1 place, and private methods would be organized somewhere else - this is personal preference.
Ive tried to define class methods in php like:
private function MyPHPClass::myFunction(){ }
when the definition isnt directly inside the class block( { } ), but i havent had any success doing this.
Ive been through all of the pages on php.net, but couldnt find anything like this. Im assuming that there is no support for something like this, but thought i would ask anyway.
thanks
You can't do this. The class declarations are Java-like.
You have to put everything in one file or, at minimum, have some helper classes -- be they only static methods to which you forward or calls or with you deferring some implementation to encapsulated objects. You can also use the __call and __callstatic magic methods to reduce the size of your stubs, but that only works for public methods and I would recommend that you avoid magic methods.
EDI2: As RobertPitt pointed in a comment, you should consider alternative strategies that divide the functionality between several classes. It has the added advantage that it can make your code more decoupled. If you need, you can still unify the functionality of the several classes behind a façade.
EDIT: By using magic methods, I mean something like this:
class MyClassHelper {
public function method_one(array $args) {
...
}
public function method_two(array $args) {
...
}
}
class MyClass {
/**
* #var MyClassHelper
*/
private $helper;
private static $ALLOWED_METHODS = array("method_one" => NULL,
"method_two" => NULL);
public function __call($name, $arguments) {
$name = strtolower($name);
if (array_key_exists($name, self::$ALLOWED_METHODS) {
$helper->$name($arguments);
}
else
throw new Exception(...);
}
}
I should recommend that you avoid this, there are many pitfalls to this (handling of references, no code completion).
Im not really a C++ / C# Programmer but interfaces in php i can give you an exampe to see if this helps.
Interface
interface IDatabase
{
public function connect($dns = '');
public function disconnect($flushCache = false); //Do not use braces, Code free in interfaces
}
Database abstract base class
abstract class Database
{
//Some driver logic here to laod mysql,oracle etc
}
MySql Driver
class DBDriver_MySQl extends Database implements IDatabase
{
public function connect($dns = '')
{
//Connection logic.
}
public function disconnect($flushDns)
{
//Disconnect Login
}
}
Hope this is what your looking for.
Related
I'm a bit lost here because I want to do something that is very easy in Java but seems a bit complicated in PHP.
We are building an SDK for our product and in Java, we have this one class that must not (!) be instantiated by the user (i.e. the coder), since there are several constraints regarding it's integrity. So we've built that as a nested class "X" inside of the "XFactory" and you will get an instance of X by calling XFactory.buildMeMyX(); - Easy...
Now PHP does not support nested classes at all, and I wonder how to apply the same here. In Java, X's constructor is hidden (private), so only XFactory can call it.
In PHP, it looks like I will have to make __construct() public and move the nested class X out of XFactory. Hence, the user will be able to create an instance without the Factory.
Now - I COULD move the factory functionality to X itself and move all the stuff there, but this would kind of break the design of the SDK. Is there a useful way to do such things in PHP after all?
For PHP 5.x you already described your options, there are no private/protected classes or inner classes at all, so there is no further way to restrict instantiation.
However, with PHP 7 this is going to change.
There are still no nested classes (although we might get them in the future, see: https://stackoverflow.com/a/31454435/664108), but you could instantiate an anonymous class and only provide the consumer with its interface like this:
class XFactory
{
public function buildMeMyX()
{
return new class() implements XInterface {
public function doWhatEverAnXCanDo()
{
// X X X
}
// ...
};
}
}
interface XInterface
{
function doWhatEverAnXCanDo();
}
As the others have said, there currently is no clean way to implement this behavior in PHP. In my opinion, the only valid use case for private constructors are factories inside the class that implement that factories.
Whenever you try to get around that use case it gets messy. No one should ever try to invent clever ways to bypass PHP's language limiations.
I just violated that rule by myself just to prove it is indeed possible. But please refrain from using that in production, or better: using it anywhere. I will try to find some bulletproof arguments for that suggestion and edit the answer afterwards.
<?php
class Dependency {}
class SomeClass {
protected $dep;
private function __construct(Dependency $dep)
{
$this->dep = $dep;
}
public function doSomething()
{
var_dump($this->dep);
echo "Doing Stuff and even having dependencies";
}
}
class SomeClassFactory {
public function buildSomeClass()
{
return $this->instantiateSomeClassWith(new Dependency);
}
protected function instantiateSomeClassWith()
{
$reflectionClass = new ReflectionClass('SomeClass');
$someClass = $reflectionClass->newInstanceWithoutConstructor();
$constructor = $reflectionClass->getConstructor();
$constructorClosure = $constructor->getClosure($someClass);
call_user_func_array($constructorClosure, func_get_args());
return $someClass;
}
}
$factory = new SomeClassFactory();
$someClass = $factory->buildSomeClass();
$someClass->doSomething();
?>
Output: object(Dependency)#2 (0) { } Doing Stuff and even having dependencies
The theory is simple. The constructor of the class that will be built via the Factory is made private. We make use of reflection within the factory to create an instance of the class without invoking the constructor.
Once we have an instance, we grab the closure of the constructor and invoke it via call_user_func_array(). That way you can make use of Dependency Injection just as you would if the constructor was public.
As I said before. That way is a single smell. By creating an object without invoking it's constructor, there is no real way to validate an objects state upon creation
This is a proof of concept, but the concept sucks.
There is no native way to do so, yet. However, if you really want to "enforce" that your class is only created from your factory class, there is a little "hackish" way to do so limiting the instantiation by inistantiating class.
class X
{
function __construct()
{
new Y();
}
}
class Y
{
function __construct()
{
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
if (!isset($trace[1]['object']) || !($trace[1]['object'] instanceof X)) {
throw new \RuntimeException('This is a private class');
}
}
}
new X(); // All is fine
new Y(); // Exception
Please note that there is no "real" way to protect the class from being instantiated from elsewhere even using this approach - it still can be done via reflection by bypassing the constructor, or simply modifying your source.
I'm just learning about PHP's interfaces as I have never really used them before, but as I understand it they are only a interface, as they are called, to kind of uphold how classes that implement them are structured?
So for example, if you wanted to make two different classes for two different databases you could do:
class mysql {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
...and that would technically be the same as:
interface database {
public function connect() {
}
public function getData() {
}
}
class mysql implements database {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB implements database {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
...am I right? It's just that using an interface it makes sure you don't go doing something like the below and hence not being able to change databases easily?
class mysql {
public function connect_mysql() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB {
public function connect_mongo() {
// code here
}
public function getData() {
// code here
}
}
Is that pretty much the reasoning behind them?
What the interface does is it standardises what your code can rely on, and at the same time decouples that from a specific implementation. Wow, that sounds complicated. It's easier to illustrate it from the perspective of a user of interfaces:
function (MyDatabaseInterface $db) {
$db->connect();
$db->getData();
}
Type hints are a big part of using interfaces. This function declares that its argument must be an instance of MyDatabaseInterface, in other words, any object that implements MyDatabaseInterface. It is entirely up to you what specific object that is, as long as it implements MyDatabaseInterface. And since in MyDatabaseInterface you have specified the methods connect() and getData(), you can be sure that any object being passed in has these methods and that you can call them.
The other way around, have a look at this function:
/**
* #return MyDatabaseInterface
*/
function foo() {
...
}
It is irrelevant what this function does internally, but it declares that it will return an object of type MyDatabaseInterface, in other words some object that implements MyDatabaseInterface. When you call it, you know what you can rely on:
$bar = foo();
$bar->connect();
$bar->getData();
This function may return an instance of mysql or of mongoDB, it is none of your concern. You simply stick to what was declared in the interface and your code will work regardless of what specific object you get.
An interface literally defines the interface between code. It defines what methods code can safely call on other code, without tying down the specifics to specific classes. Your specific objects could define a ton more methods than are defined in the interface; an interface does not declare a class structure. A class could implement several interfaces at once, meaning it implements all the methods of all the interfaces; each individual interface would then just represent a subset of all the possible methods that could be called on an object.
You should describe specific "tasks" or "abilities" which can be accomplished in an interface, not "classes". It's a good sign if your interface names end with "-able", like Iterable. A class can then implement several interfaces and thereby describe all the things it "can do". You can then require function arguments with a certain "ability" at specific points, as shown in the example code above. This isolates and decouples parts of code from one another, which makes your code more flexible, reusable and adaptable to change.
For a useful real world scenario, imagine a larger development team which is working on a large project. There are several sub-teams, each responsible for a different part of the application. They all sit down together and come up with a general plan. At some point, the code of these separate teams needs to interact with each other. They can define these interfaces upfront:
"I'll need to call some method on your code that gives me the user credentials."
"OK, then you'll need to give me some object from which I can get the foobar."
"Then over here we'll have to talk to Joe's component to send the baz data."
...
They can define the different methods they will need to talk to each other in an interface before any code has been written, then go off and do their own thing. They can rely on code which hasn't even been written yet, because they already decided on what the interface will look like. They can even substitute the real code with mock objects for the time being while Joe is still hammering out his real code, then simply switch it in later with whatever Joe comes up with. And all those techniques are useful even if you're just working by yourself.
Through my multiple studies I have come across the factory method of setting session and database objects which I have been using while in development. What I am wondering is, putting aside personal preference (although I will soak in any opinions anyone has), does this general method work, and is it efficient (meaning, am I using it correctly)? If it is not, do you have suggestions for how to improve it?
Background
I created the code this way so as to pass a database and session object to the class upon calling the class. I wanted to be able to pass along the relevant objects/references so that they could be used.
The Call Class
This class is meant to call static functions, like so:
class CALL {
public static $_db, $_session;
public status function class1() {
$function = new class1();
$function->set_session(self::$_session);
$function->set_database(self::$_db);
return $function;
}
public status function class2() {
...
}
...
}
The _set class
class _set {
public $_db, $_session;
public function __construct() { ... }
public function set_database($_db) {
$this->_db = $_db;
}
public function set_session($_session) {
$this->_session = $_session;
}
}
Now the classes referenced.
class class1 extends _set {
function __construct() { ... }
function function1() { return "foo"; }
...
}
So, moving forward, the classes would be called using CALL::class1 or CALL::class2. After that, they can be accessed as per usual, aka:
CALL::$_db = $database->_dbObject;
CALL::$_session = $_SESSION;
$class1 = CALL::class1;
echo $class1->function1(); //prints "foo".
Read about Dependency Injection . Small suggestion from my point of view, you should never create objects like $db or $session inside other objects. You should rather inject them through constructor or setter method. It will make your code less dependant on a specific classes and it will be easier to replace all dependencies almost without refactoring (actually without one if you know hot to use interfaces).
If anyone stumbles on this, I will share with you what my solution was.
Although this exercise helped me to learn a lot, and I am sure I could take the time to create a VERY highly functional factory/Container, because this is not integral to my program and not even unique, I finally bowed to the age old wisdom of not repeating something that has already been done.
I utilized Pimple, a lightweight library that uses PHP closures to create function calls. Now, I can haave the flexibility of determining which dependency injections I want, but I also only need to inject them once. Future calls, even when they create new instances, will replicate them. While I think that, in theory, my project was workable as it was, it did indeed have the unfortunate issue of requiring you to go into the container to make changes. With Pimple I do not need to do that. So I've tossed by Container class and picked up a lightweight program from the maker of Symfony. While this may not be the best answer for everyone, it was for me. Cheers!
I have studied in php oop and stocked in the concept of reusable code.
I have seen an example like
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
And implement it:
// Implement the interface
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
I can understand the code but not sure why it is reusable. Every time I want to add a new function in iTemplate interface, my Template class needs to be changed too. I don't understand the concept of "reuse". I appreciate any help. Thanks.
Interfaces aren't directly for code reuse. They are for abstraction. They enable classes that use the template to check for the interface instead of the base template class. That way it separates implementation from the interface declaration.
So if your method does something with a template class, checking for an object of instance template would hard code a dependency on that class. But in reality you don't care what class you get, you just care if it adheres to the iTemplate interface (since that's all you're calling anyway).
public function foo(Template $template) {
vs:
public function foo(iTemplate $template) {
Now, as far as code re-use, interfaces aren't really designed for that. Inheritance typically is. Basically think of inheritance as extending an abstraction. Let me give you an example:
If you were to create a set of classes for birds, you could approach it with inheritance and without it. Let's see how we might do it without:
interface iBird {
public function fly();
public function speak();
public function swim();
public function walk();
}
class Duck implements iBird {
public function fly() {
//Fly here
}
public function speak() {
// Quack here
}
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Turkey implements iBird {
public function fly() {
//Fly here, but limited
}
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
public function walk() {
//Walk here
}
}
Now, this is a simple example, but you can see that in those two birds, the walk() functions will likely be identical (and hence violate DRY)...
Let's see how that might look with a single tier inheritance:
abstract class Bird implements iBird {
public function fly() {
//Fly here
}
abstract public function speak();
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Duck extends Bird {
public function speak() {
//Quack here
}
}
class Turkey extends Bird {
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
}
Now, you can see we just re-used 3 of the methods! We didn't declare speak(), since it will be always overriden (since no two birds sound alike).
Sounds good right? Well, depending on our needs, we may want to add other abstract types. So lets say we were making a lot of different types of birds... We would have some that didn't swim, so we might create an abstract class NonSwimmingBird that extends Bird, but throws the exception for us. Or a NonFlyingBird, or a ShortRangeBird...
Now, we're really on the track as far as code re-use, but we're hitting a wall in another area. Suppose we have a bird that doesn't fly or swim. What class do we inherit from? Either way, we're duplicating code. So we need to find another way out. Well, how do we do it? Through Design Patterns... Instead of direct inheritance, we could use a decorator pattern to add those traits on the fly. (There are other patterns that can be used here, the point is to show that inheritance alone won't suit all needs. And Patterns alone won't either. You need a good architecture using both worlds based upon what your exact needs are)...
The point is, it all depends on your needs. If you only have 2 "classes" of objects you're going to architect something much simpler than if you are planning on having thousands. The point of what I wrote here is to demonstrate how you can use straight inheritance to enforce some DRY principals (but also how straight inheritance can cause code duplication as well). The big thing, is don't try to stick to DRY just because you don't want to repeat yourself. Stick to DRY, but make sure that you're combining and extending where it's reasonable to, otherwise you're creating yourself a maintenance headache. Stick to the Single Responsibility Principal, and you should be fine...
Interface writes only 1 time in beginning of development. And only after this writes other classes implements of this Interface. Interface - is a fundament.
Note: method setVariable isn't required. There are good magic methods in PHP as __get(), and __set().
Interfaces are usually useful in cases where you want something to be interchangeable. Imagine you'd build a Plugin aware application. You then have the interface iPlugin:
interface iPlugin {
public function init();
/* .. */
}
and all Plugins would implement that interface. A plugin manager could then easily check if a Plugin implements the interface and call the init() method on it.
Code doesn't need to be OO to be reusable, although in many cases that helps.
Code certainly doesn't need to use interfaces to be reusable, although again in some cases that will help.
The key to writing reusable code is to write code that is clearly written, well-commented, uses consistent naming and calling conventions, and is more general than it strictly needs to be for the problem at hand.
One of the simplest and most powerful techniques for writing reusable code in PHP is writing methods that accept either a variable number of arguments, or accept an associative array of parameters.
Often, code that didn't start out "intending" to be reusable turns out to be something you'll want to reuse. Typically, code starts "inline" and then you discover you need to do exactly, or nearly exactly, the same thing in more than one place. When you find yourself copying and pasting code it's time to refactor it as a function.
Similarly, when you find yourself wishing a function you had defined in file X would be really helpful in file Y, it's time to move it into a module.
The best way to learn all this is by experience. Some people will tell you to architect this stuff from the beginning, and that's certainly a good idea if you have the insight and experience to do so, but it's just as valid to do so from the bottom up, and it's probably the best way to learn.
Reusability of Object oriented Programming is the use of previous class or function or method in the present class but no problem of previous class.
How is it done?
I have a Model class that is the parent to many sub-classes, and that Model depends on a database connection and a caching mechanism.
Now, this is where it starts getting troublesome: I have no control over how each object gets instantiated or used, but I have control over methods that get used by the sub-classes.
Currently I have resorted to using static methods and properties for dependency injection, as such:
class Model
{
private static $database_adapter;
private static $cache_adapter;
public static function setDatabaseAdapter(IDatabaseAdapter $databaseAdapter)
{
self::$databaseAdapter = $databaseAdapter;
}
public static function setCacheAdapter(ICacheAdapter $cacheAdapter)
{
self::$cacheAdapter = $cacheAdapter;
}
}
Which has worked out well, but it feels dirty (it creates a global state for all Models).
I have considered the factory pattern, but that removes the control of the instantiation from the sub-classes (how do I instantiate an object with a variable number of parameters in it's constructor?).
Now I am at a loss. Any help would be appreciated.
As far as I know this is a perfectly acceptable alternative. Another possibility suggested by Sebastian Bergmann, the creator of PHPUnit, is to have a $testing static property. You can read his recent article regarding the Testing of Singletons. It sounds like you have similar issues.
You're solution would be fine for setting default adapters, but I'd add a way for the individual models to have a different adapter. Consider this:
abstract class Model {
protected $_database_adapter;
protected $_default_database_adapter;
public function getDatabaseAdapter() {
if(!$this->_database_adapter) {
if(self::$_default_database_adapter) {
$this->_database_adapter = self::$_default_database_adapter;
} else {
throw new Exception("No adapter set yet");
}
}
return $this->_database_adapter;
}
public function setDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
$this->_database_adapter = $databaseAdapter;
}
public static function setDefaultDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
self::$_default_database_adapter = $databaseAdapter;
}
}
Of course you could extract all static methods/properties into a Registry, Container or anything else as central.
For example, perhaps you don't want to collect data from the same database host over your whole application. Then your original script would look like the following:
Model::setDatabaseAdapter($default);
$my_model->query('....');
Model::setDatabaseAdapter($another_adapter);
$my_other_model->query('....');
Model::setDatabaseAdapter($default);
which is awfully alike:
mysql_select_db('default_db');
mysql_query('...');
mysql_select_db('other_db');
mysql_query('...');
mysql_select_db('default_db');