0

I have an old site to bring up to standard but I have to approach things in a certain way due to timing issues and certain restrictions preventing my urge to restructure the whole site properly from the bottom up.

Most of the work involves updating various include files. So, these include files are called into a page which uses a class to generate an object, as usual,

The Problem:

There are lots of pages and they are not consistently coded (thanks to sub-standard previous developers on the site), so sometimes the class I want to use is in an object called $database, sometimes on other pages the object is called $dataBase, $connection, etc. etc.

There are several includes that I am working on and I feel that having to create a new object for each include on each page is extremely inefficient, hence this question:

Can I find out from PHP which, if any, object variables use a certain class?

An illustration:

Page index.php

require "class.sausages.inc.php";
$hotdog = new sausages();

$hotdog->somefunction();
//etc. etc.

include "some_file_i_need_to_work_on.php";

include "/folder/some_other_file_I_work_on.php";

//etc. etc.

Page index2.php

require "class.sausages.inc.php";
$hotdogs = new sausages();

$hotdogs->someOtherfunction();
//etc. etc.

include "some_file_I_need_to_work_on_3.php";

include "/folder/some_other_file_I_work_on.php";

//etc. etc.

So I need to work on the includes and so for each include file I do not know for sure the $name of the variable object created in the includes parent file. All I have is that it uses the class sausages.

Solution attempts

I read how to check if object of a class already exists in PHP? which has pretty much the same issue but the solution marked here is to generate a global, which I'm feeling is another layer and to be honest I'm not quite comfortable with it as an efficient solution.

What I am trying to avoid is a situation where each include on a particular page has to generate its own object, all from the same class (usually) established in the parent page.

As there's no guarentee in one include if another include is included, I don't think I can generate an object that the includes can all use collectively, or if I can, how can I do that?

What I would Like

I want to be able to find a way to establish in PHP:

has any object been generated using this class?

yes? Use that object in this include.

no? generate a new object from the class file.

Is this possible?

Notes:

  • There are about a dozen include files,

  • There are a lot of parent pages (50+). I think editing each one would be inefficient (but this will be done at a future point)

  • Some parent pages contain some include files, some contain others. There's no guarentee which includes are included in which files ( as far as I can tell so far).

  • Most but not all parent pages have already established a class object.

  • PHP 5.6.16

Community
  • 1
  • 1
Martin
  • 22,212
  • 11
  • 70
  • 132
  • You could have an easier life if you would use interfaces – B001ᛦ Dec 15 '15 at 17:00
  • @bub Could you illustrate how interfaces would help me here? As I say, it's an inherited site which has been modified, again and again by different people over a long time period. I would like to restructure it from the ground up but that's outside of what I can do, at the moment – Martin Dec 15 '15 at 17:04
  • Even though using interfaces is generally a good thing, having a global variable implement a certain interface would be of absolutely no benefit to you in this situation. – Karolis Dec 15 '15 at 17:30
  • @karolis that is what I suspected but I don't generally use interfaces, so I have less practical experience of them. I will give it a mull over this evening and unless something amazing happens tonight, mark your answer tomorrow. Cheers. – Martin Dec 15 '15 at 17:46

2 Answers2

4

as per:

http://php.net/manual/en/internals2.opcodes.instanceof.php

You can check if certain variable is an instance of certain class:

    if ($hotdog instanceof sausages){
        // use $hotdog
    }

    else {
        // create and use $hotdog
    }

But it will not tell you anything about other variables.

You can also use this:

http://php.net/manual/en/function.get-defined-vars.php

to get a list of all defined vars into an array. You can then loop through the array to see if there are any instances of the class that you are interested in.

    foreach (get_defined_vars() as $var)
    {
        if ( $var instanceof sausage) {
            // use this var
        }
    }

This solution will do what you want, however you should note that it is probably safer to create a new object. When you use an already instantiated object inside an include, you have no idea what other operations have been performed with that object. THe sausage may have very well be fried by the time you start using it and it may not do exactly what you want.

You should also look into a singleton pattern .

Using this pattern you can always get an instance of the same class and be sure that there is only one instance created across the app.

To go back to your old app, say that you want to make sure there is only one instance of sausages class across the app.

  • define a singleton method inside the sausages class
  • search/replace all the occurances of new sausages with sausages::singleton()
  • inside the include, you can then safely use $hotdogs = sausages::singleton();

This will make much cleaner code than trying to detect wether there are any global instances of sausages.

Community
  • 1
  • 1
Karolis
  • 2,580
  • 2
  • 16
  • 31
  • Thanks. `instanceof` is close enough to what I'm looking for, I would combine it with `get_defined_vars` to see which are the object, as you point out. I'm aware the object inherited from the parent could be unsuitable but the coding for the current site is (mostly) not true objects and more using them as abstract classes. – Martin Dec 15 '15 at 16:41
  • instance of is a sign of a bad design. Use interfaces. Be solid! – B001ᛦ Dec 15 '15 at 17:00
  • 1
    You might want to read the first sentence of this issue again @bub – Karolis Dec 15 '15 at 17:06
0

For conclusion; I ended up taking Karolis' answer and generating a search system for the correct object variable, without needing to instigate a new one if one is already defined:

At the top of each of my includes:

foreach (get_defined_vars() as $varKey => $variable) {
    if(is_object($variable) && $variable instanceof sausages) {
        $$varKey = $variable;
    }
}

//$$varKey = this is the instance object. 

Obviously code for if no instanceof is set is not detailed here, but this code works for me so far.

Martin
  • 22,212
  • 11
  • 70
  • 132