View Full Version : A couple of questions about efficiency with OO and file parsing
brothercake
02-19-2005, 05:06 PM
First - am I correct in thinking that if a variable is only needed within the scope of a single method, you may as well (and it's more efficient to) define it as $foo rather than $this->foo ?
Secondly, when opening and parsing a file to do string replacement (an HTML template, where things like {FORM_MESSAGE_DATA} are parsed into the relevant post data then output) - am I right in thinking that it's faster to use file_get_contents() and do str_replace() expressions on the whole content, than it is to use file() and iterate by line, doing the replacement expressions on each line? Or is indeed there a better way, that's faster than either of those?
And thirdly (out of a couple ;)), if I have a global method which needs to be accessible to all component classes throughout a system - is it better to have a master class and instantiate all others as children of that, or to store a reference to the global method in the $GLOBALS array?
mordred
02-19-2005, 08:11 PM
First - am I correct in thinking that if a variable is only needed within the scope of a single method, you may as well (and it's more efficient to) define it as $foo rather than $this->foo ?
Definitely, but the approaches you mentioned have different semantics and are not the same, and thus can not be used interchangeably to get an efficiency gain. $foo defined in a method is a local varable indeed and stops existing at the end of the method call. So that's what you want, and what you should use. $this->foo on the other hand is an object attribute, which means that the value is bound to the object and persists for the lifetime of it, and can be accessed by other code in- and outside your object. That's a huge difference.
Whether to use one or the other is not a choice of efficiency, but of implementing correct and unsurprising behaviour of your application. Generally, use a local variable if you... eh... need a local variable. Minimizes side effects.
Secondly, when opening and parsing a file to do string replacement (an HTML template, where things like {FORM_MESSAGE_DATA} are parsed into the relevant post data then output) - am I right in thinking that it's faster to use file_get_contents() and do str_replace() expressions on the whole content, than it is to use file() and iterate by line, doing the replacement expressions on each line? Or is indeed there a better way, that's faster than either of those?
I have not got any hard numbers, but I reckon that using <?php print $formMessageData; ?>-like statements are faster to parse by the php interpreter and to print out the variables directly. If you need to get the produced content, you can activate output buffering and grab the result of the variable evaluation.
Whether file_get_contents() or file()... I think that's a very low-level detail. In your case, you need to get the full content of the template file, so a line-based parsing approach that could stop after somwhere in the middle (think of searching for a special element in SAX) doesn't work here. And since using file() would result in more code to write for no apparent use, I'd say use file_get_contents(). But if you are worried, extract the parsing method into a seperate class and benchmark both versions.
And thirdly (out of a couple ;)), if I have a global method which needs to be accessible to all component classes throughout a system - is it better to have a master class and instantiate all others as children of that, or to store a reference to the global method in the $GLOBALS array?
Depends. Is "better" related to efficiency/execution speed of the code or is it related to the overall architecture? I would base this decision on the purpose of the global method. Is it something that semantically belongs to a component class, it should go there. But if your global function (what is a global method?) acts like a registry or naming service, it should probably stand alone and not be tied into an object hierarchy. Generally, how to layer and assign the responsibilites for each class is a tricky and often discussed question.
BTW, I think you're thinking in JavaScript while programming PHP. You can't store references to functions/methods. Functions aren't variables/objects as they are in JavaScript. The object system of PHP is not as elegant as it is in JavaScript, unfortunately. References in PHP only point to objects or arrays.
brothercake
02-19-2005, 11:20 PM
Definitely, but the approaches you mentioned have different semantics and are not the same, and thus can not be used interchangeably to get an efficiency gain. [... explanation ...] That's a huge difference.
Oh totally, I appreciate that - I meant, other things being equal. So cool - that answers that question :)
Whether file_get_contents() or file()... I think that's a very low-level detail. In your case, you need to get the full content of the template file, so a line-based parsing approach that could stop after somwhere in the middle (think of searching for a special element in SAX) doesn't work here. And since using file() would result in more code to write for no apparent use, I'd say use file_get_contents(). But if you are worried, extract the parsing method into a seperate class and benchmark both versions.
Right yeah - well as I've discovered, get_file_contents is not always appropriate - when a template contains tokens which are sent to and parsed by another method, then output immediately from that method, doing the top-level parsing line by line and testing each line for what token it contains is the only way - otherwise the HTML comes out in the wrong order :eek:
But also, cool - I think I have a handle on that one now :)
Depends. Is "better" related to efficiency/execution speed of the code or is it related to the overall architecture? I would base this decision on the purpose of the global method. Is it something that semantically belongs to a component class, it should go there. But if your global function (what is a global method?) acts like a registry or naming service, it should probably stand alone and not be tied into an object hierarchy. Generally, how to layer and assign the responsibilites for each class is a tricky and often discussed question.
Right, well, this is the $64,000 question. Obviously I want it to be as fast as possible, but what "it" is, is an API manager class - it receives "events" from all over the place, and then iterates through its own data arrays looking for functions that want to be called from that event. I haven't got that far yet ... I've got as far as sending events to it from anywhere using $GLOBALS['api']->receive('event'), and that works fine.
But ...
BTW, I think you're thinking in JavaScript while programming PHP. You can't store references to functions/methods. Functions aren't variables/objects as they are in JavaScript. The object system of PHP is not as elegant as it is in JavaScript, unfortunately. References in PHP only point to objects or arrays.
I think I am yeah :) or more likely :( ...
What I want to do is store a reference to a class and its methods, for eg:
$class_name = 'some_process';
$method_name = 'some_method';
Then, at the appopriate point, instantiate the object and call its method(s) using those string references, effectively:
$foo = new $class_name();
$foo->$method_name();
Is this going to be possible by any contrivance?
mordred
02-20-2005, 01:50 AM
well as I've discovered, get_file_contents is not always appropriate - when a template contains tokens which are sent to and parsed by another method, then output immediately from that method, doing the top-level parsing line by line and testing each line for what token it contains is the only way - otherwise the HTML comes out in the wrong order
Hm, you obviously have a special situation in your mind from knowing how your code works and what it is supposed to do. I must admit I did not fully understand why your template must be parsed line by line, as I don't know how your template or your tokens look like.
You wrote "top-level parsing", "token", and "parsing" - this alls brings up one thing in my mind: That relying only on some regex or string replacement methods to subsitute text is not really parsing. It is a PITA or often outright not possible to process nested template markers in this manner. If your system needs to be that advanced (sounds so from your description), you might develop your own lexer and parser. The lexer would be responsible for creating tokens from your input data, and the parser evaluates the tokens and captures the output, maintains state/context. Just a suggestion, may sound harder than it is, though it is not a trivial task.
What I want to do is store a reference to a class and its methods, for eg:
$class_name = 'some_process';
$method_name = 'some_method';
Then, at the appopriate point, instantiate the object and call its method(s) using those string references, effectively:
$foo = new $class_name();
$foo->$method_name();
Is this going to be possible by any contrivance?
Is this also a $64,000-question? ;)
Because the answer is yes, that's indeed doable in PHP. Your example is already working code. In this area PHP has some nice capabilities, you can dynamically construct class and method names like you wrote. I sometimes use this kind of dispatch, but it can be hard to decipher later how the flow of the application goes.
<pedantic>There are no "string references". Strings aren't objects in PHP. They just a simple data type. And what you have above is variables of the type string, and use the value of these variables as names for method invocation/object creation.</pedantic>
The example above can also be done by using call_user_func(). To call a method on an already existing object looks a little funky though:
$output = call_user_func(array($class_name, $method_name));
brothercake
02-20-2005, 03:49 AM
Marvellous :) Very glad that approach is going to work - that's exactly what I was hoping for. I know I'm getting most of my terminology wrong ... I'm still fairly new to PHP ... I'm used to JS (as you know) where everything is an object :cool:
Anyway you've give me plenty to think about, and answered all my specific questions. So cool - thanks man :thumbsup:
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.