Is using php destructor appropriate for displaying HTML? - php

If a class is implemented that builds HTML for a page by constructing it and calling various methods, is it appropriate to define the display/echo part of the class within the destructor?
Instead of having a explicit Class:displayHTML(); method, having the echo $this->html in the destructor and whenever you are ready to display call unset($object); which would display it?
I know the destructor probably is not the best place for this but wonder what others thoughts are on this?

That doesnt sound feasible to me. unset does not equal echo. It's a fundamentally different thing. Also, keep in mind that objects are not only destroyed on unset but also when they are no longer referenced and/or when the script terminates. That has a lot potential for unwanted side effects.
If you dont want to have/call a displayHTML() or render() method, implement that part in __toString() and just echo the instance.
class HTMLSomething
{
/* ... */
public function __toString()
{
/* create $output */
return $output;
}
}
$something = new HTMLSomething;
echo $something;

Which of these two has a more obvious outcome?
unset($object);
or:
$object->displayHTML();
Think about that, and then go read about the Principle of Least Astonishment.

This is not the way to go because you do not have complete control over your destructor. The destructor will be called when your script finishes, but you may not want to display anything under certain conditions (say: load, validate, validation fails, display something else).
Also, as Dominic pointed out, there is the matter of readability. You don't want to read your code a year later and say: Why do I unset the object? WTF was I thinking back then?! . As you can see this will increase the WTF/minute ratio and we all know that is a bad thing.

Seems like a bad idea. I don't really see this:
unset($view);
as better than this
$view->displayHTML();
It seems the only real advantage is that you don't really need to call unset() (since at the end of the script that should happen).
However, is that really a good thing? How then do you prevent it from being displayed? Once it's set you couldn't. Or you would need a special clear() function to unset the output before it's automatically output by the destructor.
To me, I don't see an advantage here.

Related

$classInstance->title is faster than $classInstance->getTitle() - so why do most people use the slower method?

I've recently been reading up articles on how to optimize code for scalability in PHP. Several of the articles I've read today have discouraged the use of additional methods to simply return objects from a class.
So basically, they say:
If you have a class like this:
class myClass
{
public $something;
public function setSomething($val)
{
$this->something=$val;
}//function end
}//class end
$myClassInstance=new myClass;
And you want to get the class property $something, you should do this:
//echo $something from myClass
echo $myClassInstance->something;
And not this:
//echo $something from myClass using an additional method (getSomething()) that returns the property
echo $myClassInstance->getSomething();
Because there is a speed difference. The discouraged method is slower ($myClassInstance->getSomething()) which is why it is discouraged.
But, I see so many people still using the discouraged method (tutorials, code examples, ect). I could understand if they had to have the property set to private for whatever reason, but this is generally not the case.
So my question is, is there a benefit or something that I am missing to using the discouraged method? If so, what?
The reason for someone to use getter and setter methods is due to encapsulation. Directly accessing $something would render it both readable and writeable, however accessing it via getSomething() would instead just give the caller a copy (ie won't alter the original value).
What if you wanted to apply some logic to your "GetTitle" later such as filters or change some of the output by introducing special logic? You never know when these things will start popping out.
Additionnaly, people saying the function accessor style is slower are using a 1 million loops to benchmark it, but seriously, are you going to display 1 million titles on a page?

Deconstructor in PHP

After taking a look at some old code:
//Nothing like a destructor!!
function destroy() {
settype(&$this, 'null');
}
And called by
$Cache->destroy();
However in PHP 5.3 I get
Deprecated: Call-time pass-by-reference has been deprecated in /blah/-cache-.php on line 154
How should I do this?
Your immediate problem can be met by removing the & in $this, but the whole construction doesn't make sense to me. If it's not plain invalid to destroy $this from within the object's context, it's definitely not good practice.
To destroy an object, a simple
unset($Cache);
will do.
If one wants to execute stuff when the object is destroyed, one should define a destructor in the class. (The comment in your destroy() code says that this is not the point here, though. :)
Just destroy the object like normal.
unset($Cache);
I don't know why they would do that nasty looking mess above. Keep in mind that if the object has pointers in different places you will need to unset all of them - not just that one line. (singletons are an example)
The error you're getting is not related to having a destructor. The error is simply because you've tried to pass $this by reference in a function call.
PHP used to allow this, but in current versions of PHP, if you want to pass something by reference, you should specify it in the function declaration.
Therefore, your function call should look like this:
settype($this, 'null');
(ie without the &). (btw -- the word 'null' in a string??? is that what you meant?)
And if you want to pass by ref, your function should look like this:
function settype(&$object, $secondparameter) {
...whatever the function does...
}
ie with the & in the function parameter.
This rule applies in all cases in PHP. As I said, it has nothing to do with your destructor method, or with it being an object; that's just how you pass by reference in modern PHP.
Now onto the other part of your question: A destructor method.
PHP does allow for an automatic destructor function, written within your class like this:
function __destruct() {
print "Destroying " . $this->name . "\n";
}
If you write this code, the __destruct() method will be called when the object is destroyed. This may or may not be what you want -- depends on how you want it to work. The object will be destroyed when all references to it are unset or come out of scope. If you're passing the object handle around by reference, this may not happen when you expect it to -- ie the object may persist in memory even when you say unset($myobject);. In this case, it may only actually get destroyed when the PHP program finishes running. If this is the case, and you need it to be called sooner than that, you may be fine continuing with the destroy() method you have already, and calling it explicity.
Hope that answers your question.

Timing portions of a PHP script, including runtime of individual methods of objects?

I was looking for a reliable, clean way to do advanced runtime reports for specific portions of a PHP script. What I'd love to do is dynamically time and track every method call of every object during script execution, log this information, and create a table/report at the end of the script for output.
I've thought about doing something along the lines of, in pseudocode:
class MagicTimingClass redefines *ALL_CLASSES* {
public function __call($name, $args) {
log_start_time();
$return = run_the_method();
log_end_time();
return $return; // return original method results
}
}
I know I can't do this, and I've looked into runkit/classkit for PHP but I'm not sure this will help me do exactly what I'm looking for.
I'm hoping to get out a report so I can determine what methods are causing my script to bottleneck without temporarily modifying my classes for this level of debugging and then un-modifying again when I need the code to go to production.
If anyone has any thoughts or leads that would be great! Thanks in advance
You could use a profiler like Xdebug which would mean you wouldn't have to modify your code at all.

Is there anyway to get the order of the OOP method being called?

For example lets say I have a set of classes and methods to do so:
$obj->method1()->method2();
Is there anyway for method1() to know with in itself that its the first method being called or for method2 to know that its the last?
Some more details
I just want to be able to build a set of these calls so that it either returns an instance of itself if the call to the method isnt at the end of the chain or return something different if its at the end.
For example
$obj->method1()->method2(); #Here method 2 will return lets say a string.
$obj->method1()->method2()->method3(); #Since method2 isnt at the end of the chain, it should return an instance of itself (or another object) here so that the chain could continue.
EDIT: anyone whoz trying to do this - it is a bad design pattern.
This does seem to be a duplicate. Refer to this question for more answers.
Not out of the box, not even with a Stack trace.
I guess you could put something together using constants or global variables:
Don't try this at home!
$GLOBALS["chain"] = array();
$obj->method1()->method2(); // method1 adds member to $GLOBALS["chain"],
// array_push($GLOBALS["chain"], __FUNCTION__);
// method2 does the same...
print_r($GLOBALS["chain"]);
That would give you the full chain - not yet which one is the last one, to do that, you would have to pass a flag to method2().
But it would be horribly hacky and pollute your code.
Is there a specific reason you need this for?
All you could do is find out which methods have been called so far, by setting some kind of global state in the class. But you can't find out what methods are being called after a method, and you wouldn't be able to tell the difference between methods in one chain and methods in another:
$obj->m1()->m2();
$obj->m3(); // You would think that m1() and m2() came before this in the same chain
You would need to have a method at the end of each chain to clear the global state in the class.
Since it seems you need to see which method comes next in a chain, this won't work for you.
I would say that this is a really bad design pattern, at least for PHP (and every other language I've worked in). Each method should do one thing only. If you need a method to either return a string or an object depending on what you need it for later, you are doing something wrong.
Granted, I have done something like this before. It was a meta-information class for images submitted by users -- you could set it up like this:
$meta = new ImageMeta();
$meta->first_name("foo")->last_name("bar")->email("baz")->id("guid");
But, if you did this:
$meta->first_name();
it would return a string. The default value for the first parameter was NULL, and if the method got NULL, it returned a string. Otherwise it set (and escaped) an internal value and returned $this.
At first I thought it was kind of cool, but it turned out to be a mistake. I hate using that class now. Just make one method/function do one thing only and you will be much happier.
I don't think this is possible, no -- at least, I've never seen anything about this.
(Out of curiosity : why would you need that ? Maybe it would be possible to use onther solution to solve your actual problem ?)
The only way this is possible is to let the methods save some global state.
If both methods are in the same class, you could add a variable to the class and let each class set a unique value.
But the question is if this is desirable. This kind of behavior is often not very smart in the long run.

PHP constructor executes before arguments for nested variables can be supplied

First things first, here is a little snippet code to help explain my problem:
<?php
class foo {
public $title;
__construct{
echo "<html>\n";
echo "<head>\n";
echo "<title>".$this->title."</title>\n";
echo "</head>\n";
echo "<body>\n";
}
/**
*
* I get $title from index.php
*
*/
public function setTitle( $title )
{
$this->title = $title;
}
__destruct{
echo "</body>\n";
echo "</html>\n";
}
}
?>
You've probably noticed already that this code will produce a title of well, . Yah, there's an empty space there. :- )
To me this actually makes perfect sense (even if I wasn't expecting it) because the class constructor is being executed on the creation of the foo object meaning that it doesn't wait around for index.php to supply the argument for setTitle() which in turn returns the string that fills $this->title.
So if I truly understand whats going on here, what can I do to get around this issue? Should I be buffering the output using the built in buffer functions, and then modifying the stored output with the supplied title string? Any ideas?
I would really, really, really, like to keep this structure where the constructor and destructor contain this repetitive code. Its nice that these functions don't have to be called anywhere. I understand that some developers may consider this bad practice, but I am going to do it this way anyway because I want to because I think its cool. So i'm not really looking for advice in that aspect, unless you feel extremely motivated to inform me on my stupidity.
So, if you have any advice/ideas/knowlege to share with me that would be great.
Thanks, and feel free to take your time because I guess i'm going to be forced to stay inside hiding from the evil swine flu that has come to my city, so no rush!
teh_noob. Listen to me. These words that I'm typing right here. Pretend I'm saying them, and hear the words that are coming out of my mouth. No. NO NO NO NO NO! And no, I don't give a rat's butt how "cool" you think it is.
This is one of those unfortunate scenarios where it would be shorter to list the "right" things about this approach that the "wrong" things. That is to say, your problems are numerous. That being said, I'm going to go over only some of the things that are bad about this idea.
First, let's just discuss OOP in general. What you are doing here is my least favorite thing to see ever: what I call "programming with classes". That is to say, structured programming in the guise of OOP because a class keyword was used. If you're gonna do this, don't bother. Just use functions. This is class abuse plain and simple.
Classes are object blueprints.Objects lend themselves to encapsulation and instantiation. Unless you're really a fan of the Singleton pattern, why create a class that is clearly designed to be instantiated only once? And before you say "But Peter, the Singleton Pattern helps us!!!1one" try to understand that it's actually not all that great. Besides, what you're doing here isn't even a reason people turn to the Singleton pattern in the first place.
Second is the topic of subclasses. Maybe at some point in the future you'll want some popup pages for your site. Or you'll want print-only versions that are more than just CSS-driven. Maybe you'll even want something that's not HTML at all like an RSS feed. What now? How much other work that goes on in this constructor are you going to have to duplicate for these new page types to work? But what if you've already started relying on subclasses to create individual pages? Now you're fucked. Sure, you can go back and hook up the decorator pattern, but why go through all that work when this problem can be avoided by non-stupid class design in the first place?
Thirdly, is the idea of echoing HTML in the first place. I'm fine with echo for a word or two here, a tag or three there. But for large HTML chunks, it's just idiocy. Have the decency to escape to output mode and use HTML that's not locked down in a string. Not only is it easier to edit and read, you can actually work with it in a WYSIWYG should you so desire.
Fourth, this badly, badly breaks the SRP.
Fifth - this kind of ridiculous design leads to the very type of problems you're trying to solve here. Only you don't want to know that the solution is to remove the echo statements from your constructor. Is there a way around it? Sure. In fact, there's even more than one. Do I recommend any of them? No, not really.
Lastly, let's discuss headers. Maybe you haven't learned about them yet. Maybe you have and don't care. But what's going to happen when, 6 months from now, you're working on a problem and you're working inside a method that's 10 calls deep in the stack and you realize a simple header() function will solve your problem. Maybe you need to adjust the cache-control or you need to manually set the response code - whatever. But guess what, you can't. Why? Because your silly constructor outputs to the browser the millisecond it's created.
So, to recap: NO! Unless your actual, ultimate goal is to see some of your very on handiwork on The Daily WTF.
What can I offer besides admonishment? Maybe part of a new direction? Well, debugging output is hard enough in well-built systems, so don't start by shooting yourself in the foot that does it implicitly. All output from your system should be explicit. If you want to make a "page" type of class, that's fine. Just don't do it like that.
class foo
{
protected $title;
protected $headers;
public function setTitle( $title )
{
$this->title = $title;
}
public function addHeader( $header )
{
$this->headers[] = $header;
}
public function sendHeaders()
{
foreach ( $this->headers as $header )
{
header( $header );
}
}
public function printPageHeader()
{
$this->sendHeaders();
?>
<html>
<head>
<title><?php echo $this->title; ?></title>
</head>
<body>
<?php
}
public function printPageFooter()
{
?>
</body>
</html>
<?php
}
public function printPage()
{
$this->printPageHeader();
$this->printPageFooter();
}
}
$p = new foo;
$p->setTitle( 'Just Testing' );
$p->addHeader( 'Cache-control: no-cache' );
$p->printPage();
You could do all the printing in the destructor. There all variables are known. However (like you said yourself) I think this is really really bad practice. I would suggest using kind of view / template files (you anyway have time enough :) ).
You could pass the title as an argument in the constructor?
schnalle: this is bad practice. this is madness.
the_noob: madness ...?
the_noob: (shouts) THIS ... IS ... LITTLEFRAMEWORKIMBUILDING!
the_noob: (kicks separation of code and presentation down the well)
i don't really get what you want to do, but just pass the title as a parameter to the constructor ...
<?php
class Title {
public function __construct($title) {
echo '<html><head><title>' . htmlspecialchars($title) . '</title></head><body>';
}
public function __destruct() {
echo '</body></html>';
}
}
?>
if you really want your objects to print something, i'd suggest the magic __tostring() method, so you can simply echo your object. but for html tags ... still not useful.
i wish you luck with your framework, but you're either a genius (not likely) or a guy making the same mistakes (almost) every beginner did (before MVC arrived).
edit: i can't help you. you want direct output when the object is created, but need to get data into the object before it is created. so you try to workaround something ugly in making it even uglier. it just doesn't work that way!
you're trying to build a new, better kind of car by attaching wheels to a living donkey, then complain because it somehow didn't work out as you expected (donkey on wheels! wheooo!), and now you ask the community how to attach taillights in a way that makes the donkey/car go faster.

Categories