Solved

Classes and Functions

Posted on 2003-11-18
16
261 Views
Last Modified: 2006-11-17
I have 2 classes, Results_Parser, and Engine_Data.
The Results_Parser class will take some data and parse it out into usable data formats.  One of the data formats is form_data.  The Engine_Data class has a need to access the information in Results_Parser->form_data.  This is done using a function inside of Engine_Data, called get_engine_hits.  How can I get the class Engine_Data to look at something in Results_Parser->form_data?

Caveats:  Cannot instantiate Results_Parser in Engine_Data, it's not relevant.
Do not want to have to instantiate Engine_Data inside Results_Parser, the code will get unnecessarily convoluted that way.  It is the simple matter of being able to pass data from one class to the other.

Additional info:  Results_Parser->form_data may or may not exist.  What I need it the function insdie of Engine_Data to do is to check if Results_Parser->form_data exists.  If it does, then to use it.  If not, then to use other data NOT generated within Results_Parser.
0
Comment
Question by:mcogan1966
  • 9
  • 7
16 Comments
 
LVL 11

Expert Comment

by:shmert
ID: 9772553
You should pass an Engine_Data object BY REFERENCE to a method in Results_Parser.  This method will set the form_data in the Engine_Data object.
0
 

Author Comment

by:mcogan1966
ID: 9772859
I don't understand how to do that.
If Results_Parser is instantiated, it is done BEFORE Engine_Data.
Otherwise, Results_Parser will not be instantiated at all.
class Results_Parser {
.
.
   function do_something() {
.
    }
}

class Engine_Data {
    function something done() {
// if Results_Parser::do_something() exists, give me the output
    }
}

Does this make any sense?
0
 
LVL 11

Expert Comment

by:shmert
ID: 9773192
It looks like you're using static method calls, instead of actually instantiating the objects in question.  Here's how I  picture the code working:

class Results_Parser {
.
.
   function parse_results(&$engine_data) {
        $data = array(1,2,3,4,5); // this is the parsed data
        $engine_data->setEngineHits($data[1]);
    }
}

class Engine_Data {
}

$parser = new Results_Parser();
$data = new Engine_Data();
$parser->parse_results($data);
print_r($data);
0
 
LVL 11

Expert Comment

by:shmert
ID: 9773195
If this doesn't help, can you give me a more concrete example of what these classes are doing?
0
 

Author Comment

by:mcogan1966
ID: 9773327
I got a different idea from talking to someone else.  How about I have Results_Parser extend Engine_Data?

class Results_Parser extends Engine_Data {
        function do_something() {
        return $out;
        }
}

class Engine_Data {
         function something_done() {
// How do I tell here if Results_Parser->do_something() gave me anything in $out?
         }
}

This should help things along, but I'm not quite sure where to go from here.  I still need to know what the syntax is to get Engine_Data to know what Results_Parser->do_something() returned.
         
0
 

Author Comment

by:mcogan1966
ID: 9773399
Actually, with this layout, it is probably that the only class that will be instantiated will be Results_Parser.  Since it extends Engine_Data, won't it also instantiate when Results_Parser is?

If so, then I can reference functions in either by the same handle, right?
0
 

Author Comment

by:mcogan1966
ID: 9773502
$parser = new Results_Parser();
$data = new Engine_Data();
$parser->parse_results($data);
print_r($data);

...is incorrect.

Results_Parser is NOT parsing any data from Engine_Data.
They are 2 seperate classes, each with their own functionality.
However, it has been determined that Engine_Data needs some input from one small part of Results_Parser.  Hence the function "do_something()".  It was determined that Engine_Data is the core class, and that it is relevant to everything else going on.  By extending Results_Parser from Engine_Data, it is hoping that we can call just Engine_Data if we like, or call Results_Parser and get Engine_Data with it when we need.
0
 
LVL 11

Expert Comment

by:shmert
ID: 9773696
Try to explain what these 2 classes _do_.  I think explaining it in some more detail would help.

What does results_parser parse?
What does an egine_data instance represent?
What attributes do both classes have?
What methods?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 11

Expert Comment

by:shmert
ID: 9773712
In my code

$parser = new Results_Parser();
$data = new Engine_Data();
$parser->parse_results($data);
print_r($data);


The parser isn't parsing data in the engine, it is setting an attribute in engine_data with the result of the data that it parses (from somewhere else)

I think subclassing is a bad idea, since you seem concerned about maintaining a good semantic OOP hierarchy and separation.
0
 

Author Comment

by:mcogan1966
ID: 9773927
No, it doesn't.
You are passing $data, which is instance of Engine_Data() into $parser, which is an instance of Results_Parser().  That is NOT what I am trying to do.

And no, extending / subclassing is NOT a bad idea, it is exactly what this code needs to be doing.  Just because you don't want to write you code that way doesn't make this wrong.  You are assuming too much about the code, and not focusing on the specifics of the question.

My ONLY concern, and I will repeat it one more time for you, is to find a way to get Engine_Data->something_done() to know what is returned from Results_Parser->do_something().  Nothing else in either of these 2 classes has anything to do with each other.  Since the Engine_Data object is crucial to all the code, extending Results_Parser off of it for when it is needed is the correct solution.  Not all cases will require Results_Parser to be instantiated, but all cases will require Engine_Data.  Since Engine_Data needs to know IF Results_Parser->do_something() has occured, then having some code like

if(function_exists('Results_Parser->do_something()') {...}

will tell me that we did in fact instantiate Results_Parser.  If so, then I want the output from Results_Parser->do_something().  Nothing more.
0
 

Author Comment

by:mcogan1966
ID: 9773938
It should be noted for the record that each class does have a instance function that does get called when the class is instantiated.  So, there is a Results_Parser function in the Results_Parser class.  Same with Engine_Data.
0
 
LVL 11

Expert Comment

by:shmert
ID: 9774112
That's an unusual approach to subclassing, given that you stated several times that these classes have nothing to do with each other.  Usually a subclass is like a more specific type of its parent class.

e.g.
class Person {
    function firstName() {}
    function lastName() {}
}

class Student extends Person {
    function gradeLevel() {}
}

class Teacher extends Person {
    function degree()
}

I think if you could explain a little better what the classes you are architecting do (besides the fact that they have nothing to do with each other) then the simple act of describing them might make apparent a solution that wasn't apparent before.  However, I am beginning to doubt that you will do so.  Without more information I cannot help you, sorry.
0
 

Author Comment

by:mcogan1966
ID: 9778891
Then think of it in this relationship, Engine_Data 'may have' Results_Parser.  I guess in this case, it would be a 'has a' relationship, sort of.  Perhaps, instead of subclassing, I should consider instantiating Engine_Data inside Results_Parser?  In that case Results_Parser would have Engine_Data, or we can get Engine_Data on it's own elsewhere.
0
 
LVL 11

Accepted Solution

by:
shmert earned 125 total points
ID: 9780196
Sounds good!

Something like this?

class Engine_Data {
    var $parser
    function engine_data() {
        // constructor stuff here...
    }

    function &getParser() {
        // lazy initialization of the results_parser object,
        // it is not created until needed, after which the
        // same object is reused.
        if (!$this->parser) { $this->parser =& new Results_Parser(); }
        return $this->parser;
    }
    function setParser(&$parser) {
        // explicitly set the parser object which is to be used
        $this->parser =& $parser;
    }
}

You can use the "lazy initialization" pattern above, instead of "if(function_exists('Results_Parser->do_something()') {...}"
Always try to get in the habit of passing objects using the reference assignment (&)
0
 

Author Comment

by:mcogan1966
ID: 9780652
Basically, that's what I did.
I took Engine_Data, and DID instantiate Results_Parser inside it.
I just set up Results_Parser to hold off doing some things based on some more input.  I can now call a method inside Results_Parser by reference within the instance of Engine_Data.
0
 

Author Comment

by:mcogan1966
ID: 9790098
And of course, that all got changed the minute I had it worked out.
So, now I am having Result extend Engine, and making an instance of the Engine constructor within Result.  Why?  Because that's the way the lead tech wanted it done.
Oh well.  At least the code all works now.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now