August 31, 2015

Checking if an instance's class implements an interface?

Wilco’s Question:

Given a class instance, is it possible to determine if it implements a particular interface? As far as I know, there isn’t a built-in function to do this directly. What options do I have (if any)?

interface IInterface
{
}

class TheClass implements IInterface
{
}

$cls = new TheClass();
if ($cls instanceof IInterface)
    echo "yes"

You can use the “instanceof” operator. To use it, the left operand is a class instance and the right operand is an interface. It returns true if the object implements a particular interface.

You can also do the following

public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
   //.....
}

It will throw an recoverable error if the $objectSupposedToBeImplementing does not implement YourInterface Interface.

September 12, 2013

The OOP way of doing things (in PHP)

Marcos’s Question:

I’m still trying to wrap my head around OOP, having been brought up in procedural coding a long time ago. Been stretching my legs in PHP for a while now.

So I’ve read a lot about best practices and paradigms and such. Especially SOLID. And I’ve tried to do things in a number of different ways. MVC-style, I ended up with extremely long, convoluted models that were either tightly couple to everything else, or had to be injected with half a dozen dependencies. Then I swung back to fat controllers, who did pretty much all the work and the models were only like helpers.

Now, I need a judgement on my current approach. Would this be a valid (SOLID) OOP way of doing a user-account-management system:

class PDO_Wrapper { # wraps PHP's PDO functions nicely
    public function select(...);
    public function insert(...);
    public function delete(...);
    public function update(...);
}

class ORM extends PDO_Wrapper { # very basic
    public function load($id); # assigns everything in row $id to object paramters
    public function save(); # writes all object parameters to db
}

class User extends ORM { # some User specific functions
    public function hashPassword($password);
    public function sendConfirmationMail();
    ...
}

class Login extends User { # one model for each User action (login, register, forgot password...)
    public function login($input);
}

Well, I dont know which one of SOLID priniciples are you following:

Lets break down your code

class ORM extends PDO_Wrapper { # very basic
    public function load($id); # assigns everything in row $id to object paramters
    public function save(); # writes all object parameters to db
}

This class, is extending PDO_Wrapper. Now lets ask, does it provide an extension of PDO_Wrapper? Actually It does, so its kind of correct. But for this:

class User extends ORM { # some User specific functions
    public function hashPassword($password);
    public function sendConfirmationMail();
    ...
}

Does User extend the ORM in some way? NO, it uses it! So very wrong. You have to create an object of it inside the class and use it like:

class User {
   private $orm_db;

   function __construct() {
        $this -> orm_db = new ORM();
   }
}

Now for this:

class Login extends User { # one model for each User action (login, register, forgot password...)
    public function login($input);
}

Login is an action done by the object of User class. So it is a method of User Class, not a sub class.

class User {
private $orm_db;

   function __construct() {
        $this -> orm_db = new ORM();
   }

   public function login($input) {
        //...
   }
}

I hope it clears some concept about OOP.

July 25, 2013

Does it make sense to clone copies of dependencies (Dependency Injection)?

Maxiscool’s Question:

Say I have a class that has a few methods that depend on another object in order to carry out their duty. The difference being they all depend on the same class of object, but need different instances of the class. Or more specifically, each method needs a clean instance of the class because the methods will be modifying the state of the dependency.

Here is a simple example I had in mind.

class Dependency {
    public $Property;
}


class Something {
    public function doSomething() {
        // Do stuff
        $dep = new Dependency();
        $dep->Property = 'blah';
    }

    public function doSomethingElse() {
       // Do different stuff
       $dep = new Dependency(); 
       $dep->Property = 'blah blah';
    }
}

Technically I could do this.

class Something {
    public function doSomething(Dependency $dep = null) {
        $dep = $dep && is_null($dep->Property) ? $dep : new Dependency();
        $dep->Property = 'blah';
    }

    public function doSomethingElse(Dependency $dep = null) {
       $dep = $dep && is_null($dep->Property) ? $dep : new Dependency();
       $dep->Property = 'blah blah';
    }
}

My trouble here is I constantly have to check that the dependent object being passed in is in the correct state. The state being newly created. So instead I was thinking of just doing something like this.

class Something {
    protected $DepObj;

    public function __construct(Dependency $dep) {
        $this->DepObj = $dep && is_null($dep->Property) ? $dep : new Dependency();
    }
    public function doSomething() {
        // Do stuff
        $dep = clone $this->DepObj;
        $dep->Property = 'blah';
    }

    public function doSomethingElse() {
       // Do different stuff
       $dep = clone $this->DepObj;
       $dep->Property = 'blah blah';
    }
}

This allows me to get one instance of an object in the correct state, and I can just copy it if I need another one. I’m just curious if this makes sense, or if I’m over looking a fundamental guideline about dependency injection and keeping code testable.

If doSomething() and doSomethingElse() both does similar things in two functions, then its a bad choice. It this case created a feeder function and feed two different object to this function.

But if there are both responsible for two different action requiring a clone of the dependency object, then it is not bad.

June 16, 2013

Call function inside static function of the class

Kriss’s Question:

In laravel framework i often use – Model::find($id)->orderedBy(param);

I would like to know how to achieve such expression. I began with this:

 Class Test
 {
    static public function write()
    {
       echo "text no 1";

       function second()
       {
          echo "text no 2";
       }
     }
 }

now i when i do

Test::write();

i get “text no 1”

what i want is to do:

Test::write()->second();

and get ” text no 2″

Unfortunately my way doesn’t work.

Is it possible ?

Excuse me for bad language – still learning.

Logically it is not possible, you cannot call second() until you have called Test::write() and you can call it later because afterward the PHP will redeclare the function. So you need to change your approach.

If you return an object from the write() method it is possible.

Class Test
 {
    static public function write()
    {
       echo "text no 1";
       return new Test(); //return the Test Object
    }

    function second()
    {
          echo "text no 2";
    }

 }

Now you can call Test::write()->second();

March 3, 2013

How can I get the child properties without the parent properties?

Question by user1020317

I’ve something like the following:

class a {

    private $firstVar;  

    function foo(){

        print_r( get_class_vars( 'b' ) );   
    }
}


class b extends a{

    public $secondVar;  

}

a::foo();
print_r( get_class_vars( 'b' ) );

The output is

Array ( [secondVar] => [firstVar] => ) 
Array ( [secondVar] => )

I pressume this is because when get_class_vars(‘b’) is called within a it has access to firstVar, but how can I get the function foo() to output just the class ‘b’ variables, without the parent variables?

Theres a solution on http://php.net/manual/en/function.get-class-vars.php which involves getting the a variables, then getting all a and b variables and then removing the ones that are in both, leaving just the b variables. But this method seems tedious. Is there another way?


Workaround I’m currently using:

class a {

    private $firstVar;  

    function foo(){

        $childVariables = array();

        $parentVariables = array_keys( get_class_vars( 'a' ));

        //array of 'a' and 'b' vars
        $allVariables = array_keys( get_class_vars( get_class( $this ) ) );

        //compare the two
        foreach( $allVariables as  $index => $variable ){

            if( !(in_array($variable, $parentVariables))){

                //Adding as keys so as to match syntax of get_class_vars()
                $childVariables[$variable] = "";
            }
        }

        print_r( $childVariables );
    }
}


class b extends a{

    public $secondVar;  

}

$b = new b;
$b->foo();

Answer by Starx

You must be running on lower PHP version. It works fine on codepad on your same code.

Demo: http://codepad.org/C1NjCvfa

However, I will provide you with an alternative. Use Reflection Clases:

public function foo()
{
  $refclass = new ReflectionClass(new b());
  foreach ($refclass->getProperties() as $property)
  {
    echo $property->name;
    //Access the property of B like this
  }
}

Preview

October 28, 2012

How to put a function inside an object and directly output the result

Question by Dan Myasnikov

Look, I ve got the following code to be executed and the result expected:

a = { a: function(){ return 'red'} }

so whenever I call

a.a #=> I would like to receive 'red' rather than 'function(){ return 'red'}

Any help appreciated

Answer by Starx

Simply do this

a = { 
   a: 'red' 
};

But if having the result return function that important, we have to make sure the function get called and returned.

a = {
    a: function() {
        return 'red-by-function';
    }() //This will ensure the function is called rather that returning the whole function
};

Demo of both cases

May 9, 2012

PHP OOP: Job of Authenticator Class to retrieve current user via session?

Question by christian

I’m in the process of reorganizing an application.

At the start of my application I need an object to be initialized to represent the current user. I am planning an authentication class to handle logging in and logging out, and I am wondering if the initial session variable check for user id and database retrieval would be appropriate for this class as well or if there is a standard protocol?

Thanks

Answer by Starx

Well, Of Course. Checking the session variables for user id at first is the right thing to do.

No matter what kind of authentication use, at a point you have to check if someone is already logged in or not. It is not even that complicated. For the simplest of use:

if(isset($_SESSION['logged_status']) && $_SESSION['logged_status'] ==1) {
    $this -> logged = true;
}

However, the database retrieval part as a session variable is not as secured as you want it to be. Although, caches records can be stored in the session without any risk.

May 6, 2012

PHP OOP how to group configuration data

Question by cl0udw4lk3r

i wanna store some configuration data in some objects, and i’ve a problem…

class B {
  const attr1 = 'something1';
  const attr2 = 'something2';
  const attr3 = 'something3';
}

class A {
  const attr1 = 'somethingA1';
  const attr2 = 'somethingA2';
  const attr3 = 'somethingA3';
  const b = <---- i wanna put here a reference of B, but B as a class (not an object...), i'm crazy?
}

I’m not sure if my example is clear… from A, i want to access to attr1 of B, like A::B::attr1, or something like this, there’s another way to do this? Or i’m wrong?

Answer by Gordon

There is no way to assign reference to a Class, nor is there a way to assign class constants at runtime. So your entire approach is pretty much impossible. What you can do is

const b = 'B' 

and as of PHP 5.3.0 you could then do

$b = A::b;
echo $b::attr1;

but you cannot do A::b::attr1. This will raise a T_PAAMAYIM_NEKUDOTAYIM error. It’s a parser limitation. PHP cannot do this as of this writing.


Because the class B contains a group of data of A, i want to store in b (of A) a complex data, i want to do like this because i wanna keep the code clean

You can solve this easily by making B a composite of A, e.g. you either inject B into A when you create A

class A
{
    private $b;

    public function __construct(B $b)
    {
        $this->b = $b;
    }
}
$a = new A(new B);

or create B inside A, e.g.

class A
{
    private $b;

    public function __construct()
    {
        $this->b = new B;
    }
}

Because B is just the data parts of A, you tunnel all public access through A instead of getting hold of B and then using B’s methods. So any code using A does not need to know there is some B inside A. This will allow you to change B easily without needing to worry about code that consumes A, e.g. to get attr1 you add a getter to A:

public function getAttr1()
{
    $b = $this->b;
    return $b::attr1;
}

You can mitigate the clumsy need for assignment when using properties instead of constants in B (constants are stupid in PHP anyway as you have to treat them as public API), e.g.

class B
{ 
    private $attr1;

    public function getAttr1()
    {
        return $this->attr1;
    }
}

And then you can do in A:

public function getAttr1()
{
    return $this->b->getAttr1();
}

Even better would be not to expose the internals of B through A altogether though and only add public methods that do something with A. This will make your API much smaller and your code more OO.

Answer by Starx

You cannot reference to a class like that, because the only way you will ever use the class is through an object, so there is no point trying to do that either.

User this:

class A {
  const attr1 = 'somethingA1';
  const attr2 = 'somethingA2';
  const attr3 = 'somethingA3';
  public $b;

  function __construct() {
    $this -> b = new b();
}

PHP dynamic class extending

Question by tim

I know you can extend a class when constructing it like the following:

class b extends a {
}

But is it possible to dynamically extend classes from the scripts? Such as:

$b = new b($input) extends a;

What I wish to accomplish is to extend the module differnetly wheither it’s used in admin rather than the public pages. I know I can create two different parent classes by the same name and only include one per admin or public. But my question is, is it possible to do it dynamically in PHP?

Answer by Cory Carson

You can’t, but this has been requested for a few years: https://bugs.php.net/bug.php?id=41856&edit=1

You can define the classes within an eval, but it’s more trouble than declaring the class normally.

Answer by Starx

Yes, as cory mentioned, this feature has been requested before. But before that, you can create a workaround. Here is my old school trick for this

Create two separate classes like these:

class a {
}
class b {
   public $object;
}

Then, create an extended version too

class bextendeda extends a {
}

In the constructor method of class b, place few functions which redirects to the extended object if requested.

class b {
    public $object;

    public function __contruct($extend = false) {
        if($extend) $this -> object = new bextendeda(); 
        else $this -> object = $this;
    }

    function __get($prop) {
        return $this-> object -> $prop;
    }

    function __set($prop, $val) {
       $this-> object -> $prop = $val;
    }
    function __call($name, $arguments)
    {
        return call_user_func_array($this -> object, $arguments);
    }

}

And there you have it, IF you want the extended version just do this

$b = new b(true);

If not

$b = new b();

Enjoy 🙂

April 26, 2012

OOP: Which class should own a method?

Question by Frungi

I’m having trouble understanding how classes relate to their methods. Is a method something that the object does, or something that’s done to it? Or is this a different concept entirely?

Specifically, in a library’s software system, should the borrow() method belong to the class representing the library patron, or the class representing the item that the patron is borrowing? My intuition is that it should read like patron.borrow(copy), like English sentence structure, subject.verb(object); but my instructor says that’s Wrong, and I don’t understand why he would have borrow() belong to the Copy class (and he doesn’t really explain things too well). I’m not looking for justification, but can someone just explain the proper relationship?

Edit: This question was closed as “off topic”. I don’t understand. Are software design questions not appropriate for this site?

Answer by Konstantin Oznobihin

Some generic words first.

Software construction is not something which should be governed by English language rules or “beauty” or whatever, it’s engineering discipline. Think of whether your design solves the problem, whether it will be maintainable, whether it will be testable, whether it will be possible to parallelize development and so on. If you want something more formalized take a look at the “On the Criteria To Be Used in Decomposing Systems into Modules” by D. L. Parnas.

As for your library example. Imagine you have a Copy outside of library, shoult it have borrow method then? How the borrowing is registered? Are you ok with either Copy or Patron classes responsible for data storage? It looks more appropriate to put borrow into a Library class. Responsibilities will be clearly divided, you wouldn’t need to know much about borrowing to implement Copy and Patron and you wouldn’t need much details about them to implement Library.

Answer by Starx

Is a method something that the object does, or something that’s done to it? Or is this a different concept entirely?

Let me clear something about class and objects first. Class are generally used to a denote particular category. Like

  1. Cars not Ferrari, or Porsche
  2. Fruits not Banana, or Apple

So, it’s Ferrari that is driven, and a banana that is eaten. Not their class

Its always an object that has properties and has behavior.

Even going to your case specifically.

borrow() method is an action/behavior done by a object of a person on an object of book whose records is kept by another object of the library system itself.

A good way to represent this in OO way for me would be like

libray.borrow(new book('book title'), new person('starx'));

Just for fun, What do you think about this

person starx = new person('starx');
book title1 = new book('title1');
library libraryname = new library('libraryname');
libraryname.addBook(title1);

if(starx.request(title1, libraryname)) {
     starx.take(library.lend(title1, starx));
}
...

Please fill the form - I will response as fast as I can!