Thoughts about __toString() in PHP

March 23, 2011

PHP is a loosely typed language(the same variable can be a string or number), but sometimes I think it should be even more loose in some aspects and allow even more magic. Maybe that was a wrong way of putting it, but especially in the case of __toString() in PHP I think that the developers copied Java without thinking the possibilities of the method, what it could have been if it was not bound to “String”. “String” is this old thing, actually one of the first things, that was created out of 0 and 1.

If you’re not familiar with __toString() method, I’ll first explain what it does. The __ tells you that this is a magic method, and it is a feature provided in an object in PHP and many other languages. The point of __toString() is to return a string value of the object if it is in a string context, or simply put, echoed. Example:


class Person {
private $fname = 'John';
private $lname = 'Doe';
public function __toString(){
return $this->fname.' '.$this->lname;
}
}

$person = new Person();
echo $person; //John Doe

For me this gives my object a new dimension. My Object is a string and an object. And I’m mostly fine with it, more than that, I love the feature.

What I would like to change is to change the __toString() method into __toValue(), or add more functions like __toArray() and __toObject() or __toWhatever() that can be used if the __toString is not set or/and in a prioritized order(I say if the __toString() is not set, because it should not be deprecated at first).

Let’s make __toArray() the example. I would like my object to be interpreted as an array in some cases if the object way is not supported. The best way to show what I mean is to use an example:


class Person {
private $fname = 'John';
private $lname = 'Doe';
public function __toArray(){
return array('fname'=>$this->fname, 'lname'=>$this->lname);
}
}
$person = new Person();
//NOT VALID PHP
echo $person['fname']; //John

//VALID PHP
$person = $person->__toArray();
echo $person['fname']; //John

As you can see, the idea is likeable – and I’m not the first one to propose the add-on. But why do I like this?
– Because it gives an Object more functionality
– You can do much more cool stuff without having to create and call functions for them
– Gives objects multiple dimensions, and makes them more rich
– Cool if you need to transform an Object into different types of structures and easily append into different situations
– You could use an Object in new places, like directly in a foreach loop
– Why should this only work with strings?
– Can give access to private and protected values of the object where casting((array)Object) does not work
– __toString() is actually faster than calling a public method toString() that does the same.
– Great way of simplifying some frameworks
– __toString() limits the use of something that should not be limited in my opinion

Why not?
– It’s not that hard to make an own toArray() method that does the magic without being magic
– Magic methods may add some more “WTF?” to some programmers
– (whispering carefully from a corner)We should not use magic methods that much? (Why not?)

Well, I really can’t think of many bad things with some extra magic. Are there other arguments for or against?

Advertisements

Ideas of March.

March 19, 2011

Oh blogging, oh blogging. Thy threshold is low, but the maintenance is big.

I like reading blogs. Especially those that have categories and tags to filter out all the stuff you don’t want to read about. The only thing that bothers me is that you often have to read a lot of blogs to find updated material on the things I care about, especially in the PHP community. Great post should be advertised and marked cool! If only the people who do have some cool code to provide could blog more frequent with a lot of cool code!! Sigh.

It’s a challenge. I know that, having some blogs out there with different kinds of content, updated every now and then. Blogging takes time if you want to do it good. People want an updated blog. Blogs does not bring that big of an income. But still, people keep blogging, I keep blogging, and you keep blogging. Every once and then someone finds your post in a time of need, and the purpose of the post is fulfilled. Do not blog for the masses, blog for the few that can evolve into masses. Blog for yourself. Blog to make a history, if only your own blogging history! That is a best practice!


Send large emails in php

March 17, 2011

I’ve encountered this problem once a long time ago, and used a lot of time finding a solution back then. Probably because no one really directly issued this problem.

When you send large text in your mail, specially HTML, you have to remember to encode the message right and chunk it. Why? The email standard RFC2822 only accepts line lengths of 998 chars, and if you send longer lines you probably encounter a lot of problems in different email clients. This may be line breaks or spaces after every chunk of 998 chars, that could be in the middle of an HTML tag or link, making the email body a mess.

To avoid this, you have to use base64 encoding on the email body header:

“Content-Transfer-Encoding: base64\r\n”

The second thing you have to do is to encode your content string with base64 and chunk it into chunks before appending to the email.

chunk_split(base64_encode($content))

base64 encoding is something email clients can read and because the sting of HTML is encoded into this format you don’t get the spaces between every chunk of content when the client displays the content.

These two lines is the only thing you probably need to append when you ha long text or large emails with data longer than 998 chars. Today I encountered this problem again, and I knew about the solution so I knew what to google to find the right answer. But I did not find it right away, because there was not any really good, and short, explanation anywhere that said exactly what I needed to do.


Problem with getting JSON from PHP using AJAX

March 3, 2011

I got this problem when I wanted to get back a json produced in PHP. Naturally, I used this header:
header('Content-Type: application/json; charset=utf-8');

It did not work, and that’s the one that everybody said I should use. So I tried different. I tried this:
header('Content-type: text/plain; charset=utf-8');

And it worked! In FireFox, in Chrome, in IE 8 on my computer, but it failed on IE 8 on my co-workers computer. WTF? Yep. Somehow it failed, and it needed a fix.

Since it failed, I can tell you that in AJAX the return value was not the expected one. I used jQuery and expected the dataType: “json” to work. jQuery does the evaluation of the data and creates a JSON object. But not this time. It failed. In IE8 the header seemed to be ignored and the value returned was wrapped in <html><body></body></html> – and yes, it seemed to be a common error somehow, except that none of the solutions mentioned that seemed to work for others worked for me. I even tried some really simple code, and it failed – but I managed to get it to work if the filename actually was .json – but then I could not use PHP. Or could I? The solution was this, with two headers in PHP:

header('Content-type: text/plain; charset=utf-8');
header('Content-Disposition: inline; filename=response.json');

And then do the

echo json_encode($array);

And voila, it worked.