Note: I have followed this post up with 12 Things You Should Dislike About PHP.
I saw this article linked to from Digg and was disappointed by the list. Here's what I think are some of the more interesting features of PHP.
- 1. Reflection API
-
PHP5's Reflection API can introspect PHP functions and classes and even allow them to be rebuilt (see this demo)! For example, PHP provides a call_user_func[_array]() function to call functions/methods given a string representation of their name; however, PHP doesn't provide such a function for classes.
class TestCallFunc {
public function __construct($a, $b) {
echo $a .' '. $b;
}
}
//call_user_func_array(array('TestCallFunc', '__construct'), array('hello', 'sir')); // will not work
$class = new ReflectionClass('TestCallFunc');
$class->newInstanceArgs(array('hello', 'sir')); // works
// the above can come in handy for certain cases where you want to unpack an array of values,
// without knowing how many elements are in that array to a classes constructor.
// If one knows the number of arguments of a constructor, or the constructor does not take a
// variable number of arguments, then this will suffice:
$class = 'TestCallFunc';
new $class('hello', 'sir');
Unfortunately the above example hardly does the Reflection API justice. Consider the following use case. Since the Reflection API can figure out almost everything about PHP code it means that it could be used as a strategy for dependency injection. By using smart type hinting within function definitions (see below) and the reflection classes, function dependencies could be figured out on the fly and be satisfied automatically.
- 2. Ticks
-
PHP has an unusual statement called declare. At the moment the statement only supports ticks (functions that are executed after every nth process/statement. The implication of tick handlers for timing and testing applications is huge. Imagine being able to chart how long specific processes take as they happen without the burden of having to manually place timing functions within the code! Another possibility would be to pass state to a tick function for analysis. In some cases this would be immensely useful for tracking down bugs or for simply seeing how data is changed throughout the different processes within a program.
- 3. list(), extract(), and compact()
-
list() is a function that PHPers learn early and forget about almost as quickly. list() allows for easy unpacking of numeric arrays, eg: array('a', 'b', 'c', ...). List can be used cunningly for simple tasks such as switching the values of two variables:
$a = 'a';
$b = 'b';
list($a, $b) = array($b, $a);
echo $a; // output: b
echo $b; // output: a
List also has a practical application for any function that returns an array. Instead of having to deal with the results as $result[0], $result[1], etc one can use the list() construct to set the values of the array to variables without the hassle of having to do each variable setting manually. Essentially, list() is PHP's way of doing multiple variable assignment.
Unpacking associative arrays is also easily accomplished with extract(). Consider the following simple example:
extract(array('a' => 'a', 'b' => 'b'));
echo $a; // a
echo $b; // b
extract() comes in handy when transferring scope variables around from one place to another is needed. By packing scope variables into an associative array using get_defined_vars() or compact() and then unpacking them somewhere else using extract(), scope variables can be transparently transported. This experiment of mine examples this use of extract().
Another use for extract() is for template engines. Many simple template engines allow their variables to be set in one place using an associative array and accessed as normal variables within the templates. This works simply by extracting that associative array from within the templates.
Special note should be given to compact(), which was mentioned in the comments by Tarique Sani and does the opposite of extract(). It acts in a similar way to get_defined_vars(); however, it gives the programmer more control by allowing them to specify which local variables to pack into an associative array.
4. PHP5 SPL
The PHP5 Standard PHP Library is full of gems. Two of my favorites include the Iterator and IteratorAggregate interfaces.
PHP5's Iterators work transparently with the foreach() construct as if they were arrays. Iterators come in handy when--for example--formatting needs to be applied to a set of data. Be it a MySQL result set or a multidimensional array, Iterators allow for the accessing, formatting it, and return of data all at the same time! The implication is that data is only fetched when it is needed and that any intermediate steps between retrieval and return of data happen transparently.
Sometimes making a class implement Iterator to allow a class to be iterated is bulky. This problem is solved by implementing the IteratorAggregate interface. It works is by defining a getIterator() function within a class that returns an iterator. If you're a Python user, getIterator() is tantamount __iter__().
Two other nifty interfaces in the SPL are ArrayAccess and Countable. Consider the following code:
class Foo implements ArrayAccess, Countable {
private $vars = array();
// ArrayAccess
public function offsetGet($key) {
$ret = NULL;
if($this->offsetExists($key))
$ret = $this->vars[$key];
return $ret;
}
public function offsetSet($key, $val) {
$this->vars[$key] = $val;
}
public function offsetUnset($key) {
unset($this->vars[$key]);
}
public function offsetExists($key) {
return isset($this->vars[$key]);
}
// Countable
public function count() {
return count($this->vars);
}
}
$foo = new Foo;
$foo['bar'] = 'baz'; // calls Foo::offsetSet()
echo $foo['bar']; // output: baz, calls Foo::offsetGet()
echo count($foo); // output: 1, calls Foo::count()
As is clear, the Foo class acts in many respects like an array. This functionality is desirable when the convenience of array-like access to a class and the power of class methods are used to enhance productivity and functionality. (As a side note, check out ArrayObject.)
When do any of the SPL classes come in handy? Consider the following object-oriented interface to a MySQL database: iterators are used to fetch the results only when they are needed; Countable allows calling of the native count() function on that query result instead of custom and unintuitive numRows() function; and ArrayAccess is used to represent each row from the database where row objects act like arrays for convenience but can implement more advanced business logic through extension.
The SPL classes allow programmers to interact with their classes more natively and intuitively than ever before. Implementing the different interfaces and classes from the SPL into code allows for transparent interaction with different data types in the same way.
5. __autoload()
__autload is called transparently by PHP when a class that doesn't exist is instantiated. Autoload will take in a class name and then go and try and find the file that the class is in, include it, and let the program continue running its course.
Although this is a handy function I suggest that it not be implemented directly. The reason why I say don't use __autoload() is because it has no namespace. Simply put, if two (or more) applications are running at the same time and share common files that both happen to define the __autload() function then there will be errors. Instead, please check out spl_autoload() and spl_autoload_register().
6. Type Hinting
Type hinting is used to make sure that the information being passed into specific functions complies with an expected data type. Unfortunately type hinting only works for objects and arrays, but it's still extremely nifty! Note: as the following example shows, PHP will error when an unexpected data format is passed to the function.
Here is an example of type hinting in action for objects and for arrays:
function test(array $a, stdclass $b) {
echo 'yay';
}
test(array(), new stdclass); // works
test('a', 'b'); // results in an error
7. Abstract Classes and Iterfaces
When classes should follow specific contracts interfaces and abstract classes should be used. Interfaces define the required functions and function arguments for all implementing classes. Abstract classes are similar in that respect; however, they also allow for functions to be regularly defined (with bodies).
Note: interfaces nor abstract classes can be instantiated directly. Interfaces need to be implemented (PHP supports multiple interfaces for classes) and abstract classes must be extended.
Obvious use cases for interfaces and abstract classes are for abstraction layers where its useful to define a single interface in one place and let extending classes implement the data-specific logic on their own. Simple examples to this would the database abstraction layers, such as ADOdb.
8. "static" keyword
This is more for php4 people and is really a hack. The most common use of the static keyword from within a function is to implement singleton factories for classes. With improvements in PHPs object-oriented model in PHP5, the static keyword is not as useful because classes allow for static methods and proper function visibilities.
function increment() {
static $count;
if($count === NULL) {
$count = 0;
}
return ++$count;
}
echo increment(); // 1
echo increment(); // 2
echo increment(); // 3
// ...
9. === and !==
These are extremely useful and most PHPers can't tell the difference between == and ===. Essentially, == looks for equality, and by that PHP will generally try to coerce data into similar formats, eg: 1 == '1' (true), whereas === looks for identity: 1 === '1' (false). The usefulness of these operators should be immediately recognized for common functions such as strpos(). Since zero in PHP is analogous to FALSE it means that without this operator there would be no way to tell from the result of strpos() if something is at the beginning of a string or if strpos() failed to find anything. Obviously this has many applications elsewhere where returning zero is not equivalent to FALSE.
10. Variable Assignment from within Conditional Statements
This is another fun trick that can also be a pain in the ass. Mistakingly doing if($result = '1') instead of if($result == '1') often happens and is a difficult bug to trace. Interestingly, this annoyance can also come in handy! Try this: check if a strpos() failed or not and get the proper result of it all from within an if() statement. If you don't know how it would work then take a look at the following code:
if(FALSE !== ($pos = strpos('aaaa', 'a'))) {
echo $pos; // echo's 0
}
11. PHP's Magic Functions
They definitely don't compare to what Python offers but they can be pretty nifty. Couple these functions with the SPL and some pretty cool classes can be made.
__call()
The __call() magic function allows for a class to call functions that it doesn't necessarily have. For example, if there are a lot of redundant functions in a class that work in very similar ways but still require a slight amount of custom logic then maybe __call() would allow for a better implementation. Consider an associative array where the keys represent a white list of functions that __call should work with and their values would somehow allow __call to implement the slight differences between the functions.
If that example seems unlikely then let me detail two ways that I've used __call.
The first way was implementing filters for different MySQL data types. Data for VARCHAR, INT, CHAR, TEXT, et al. can all be handled in very similar ways but require slightly different type casts and regular expressions checks. Well, storing the unique checks in an array with function names for each data type dramatically reduced the amount of redundant code I had to write and made the system more maintainable for when I needed to add more data types to the list.
The second way that I implemented __call() was for credit card processing APIs. I recently made a library to interact with the Authorize.net API and it was expected of me that in the event that the processor was changed that the only thing that would need to be changed is the call to instantiate the appropriate class. If anyone has worked with payment processors before then they will know that the data they accept can be crytpic (eg: x_login, x_customer_cc). To make things simple, I used call to map an associative array of keys (function names) to the processor-specific variables that they modified. Instead of setting an x_login field, I could do: $AIM->login().
__get(), __set(), __isset(), __unset()
These act similarly to ArrayAccesses offsetGet, offsetSet, etc etc, except that these functions allow you to access non-existent instance variables.
__toString()
What happens when you try to echo a class instance? Normally the output will be the unhelpful Object id #1 (or another number). This can be changed though! Changing what is returned from an echo is as simple as defining a custom __toString() method and giving it a custom return value.
12. __halt_compiler(): Halt the Compiler!
Ever wanted to make the installer for a program and the entire program to be installed fit into one file? This can actually be done by using __halt_compiler()! Check it out and make sure to look up how applications such as Phar and FUDForum take advantage of it.
I was asked how this was different from exit() so I will explain. Imagine having a PHP installer script at the top of a file and then having a compressed version of, for example, a forum (in the case of FUDForum) in the rest of the file. When __halt_compiler() is called, PHP literally stops parsing and compiling past that point. That means that the installer can open itself up, look for everything after the __halt_compiler() call, unzip it, and then store it on the server.
13. Variable Composition
Just see this experiment for more interesting implementations, but otherwise the following is possible:
${'a' . 'b'} = 'c';
echo $ab; // c
14. Chaining Method Calls
If you're a fan of jQuery then you will love Javascript's ability to chain methods. PHP5 can also do this! For example: (take note of return $this)
class Foo {
public function bar() {
return $this;
}
public function baz() {
return $this;
}
}
$foo = new Foo;
$foo->bar()->baz()->bar()->.... // these two functions can continue to be chained
The above application doesn't show any practical use for chaining so I encourage people to look at how the CodeIgniter PHP framework uses method chaining for database query building.
15. preg_split
Ever use explode() and then end up looping through the results and picking out the empty ones? Isn't that annoying? By using preg_split this tedious process can be avoided:
// instead of...
$str = "a,b,,c,d"
explode(",", $str); // array('a','b','','c','d')
// do...
preg_split("~,~", $str, -1, PREG_SPLIT_NO_EMPTY); // array('a','b','c','d')
The above example might not seem all that useful so consider bb code parsers. One of the major problems with parsing bb code is that most of the bbcode to html translators don't fix improper closing tags, or even check for them! Generally speaking, most bb code parsers will to a flat preg_replace for each of the tags.
A better approach to parsing bb code is to split the text up into parts that are text and parts that are bbcode-tag-like, eg: ~\[([^\]]*)\]~. By doing this one can go through the split up results and parse the bbcode using a stack. This allows for both proper checking of bbcode opening and closing tags along with the ability to implement a generalized solution so that adding bbcodes isn't about making a new preg_replace but rather making a class/function that knows how to correctly handle the opening and closing tags.
In one of my previous posts I use the above mentioned technique to parse HTML for special XML-like template tags.
I think that's a decent enough list for now, how you enjoyed it.
- PHP
by Peter Goodman on Aug 17, 2007 @ 10:44pm
HI,
Posted with spell out @ . at dot valid email. Got a error message requesting valid email. Did that submit got lost. If yes, can u correct u wordpress setup features.
How good are u at php? If u are expert with some knowledge of Foregn language charaset, would resubmit quetsion
by scrtadmr8 on Aug 18, 2007 @ 2:17am
Some real nice stuff here. I didn't know about variable composition, and I do have quite a few places to use it. Thank
I'm a PHP developer myself, I work professionally in the field. I just wanted to say it's nice to finally see a post that even a seasoned veteran can learn something from.
Nice one thanks
by gary on Aug 18, 2007 @ 8:55pm
"=== and !=="
Thanks for that one, was never sure what the difference between == and === is..now I know, so thanks =D
by live tv on Aug 18, 2007 @ 9:07pm
Hm. This doesn't seem too far beyond the one you were disappointed with, thought it's more intermediate. I find it hard to believe that things like list and extract, ticks, and "chaining" method calls (which is not really a PHP feature but the results of good OOP programming in any language supporting it).
PHP is in a sad state if this stuff is something "most PHP programmers do not know" =(
by David on Aug 18, 2007 @ 9:21pm
This is great stuff! I consider myself fairly advanced in PHP but a lot of this stuff I had never even seen before (__halt_compiler() ?!).
(You should add a link tag to your head for your RSS - but subscribed!)
Great post! Nice to finally see some higher level tips. Thanks!
Most of the things on this list are WAY above my head. Your examples demonstrate how to use the techniques, but I have no clue what you're achieving by most of them. Sadly, this problem is not limited to just this list; I find that most info about PHP on the Internet is not easy reading. I'm a former ASP programmer trying to switch to PHP and finding it very frustrating.
by Scott on Aug 18, 2007 @ 9:38pm
Nice stuff man. The only one I remotely use are the magic functions of PHP. Thanks for the heads up!
by Derrick on Aug 18, 2007 @ 10:13pm
Chris, thanks for the tip. There is now a RSS feed link in the head and I also put the post name into the title (dunno why I forgot that earlier).
by Peter Goodman on Aug 18, 2007 @ 10:15pm
To list() and extract() you can also add the complimentary function compact(), while extract() is great in the template/view compact() is great for sending the variables to template/view
Tarique Sani, thanks for the tip! I have never actually used that function but a quick look in the manual shows me its usefulness. I have added into my article :)
by Peter Goodman on Aug 18, 2007 @ 10:39pm
That first post on Digg definately didnt live up to the hype but this one - it was great. Thank you from your friends @ http://www.askTheAdmin.com
Good article.
For #15, i think $str = array_values($str) does the same thing.
by rabbit on Aug 18, 2007 @ 11:23pm
I just wanted to say that while I give congratulations to your attempt to "trump" the previous article about PHP tips, I would like to say that you attempt is no better. I tried reading about the first 5-6 tips, but they could not hold my interest unlike the previous article. Try keeping your tips more brief and to the point and maybe you will come up better next time.
by Rodey on Aug 18, 2007 @ 11:23pm
Rodey, I can see how my generally long posts could be dry to some people :) I actually wrote this article twice, the first time was rushed, poorly written, and lacked a lot of the meat of what's there now.
I decided to rewrite and make it longer because I didn't think it was enough to simply say: "this is interesting, figure out for yourself why." Some functions are immediately obvious, but the practical applications of others are not. For example, preg_split is a function I often use. Besides being a superior explode(), I also use it for html, bbcode, rss, and template parsing.
Further, the SPL is full of amazing classes and interfaces but some of them are advanced concepts. For people new to iterators its not completely obvious how they can be applied to an every day use.
It's understandable that some people will find this post boring; however, I can't imagine someone understanding what I see in this list without the context I have given.
by Peter Goodman on Aug 18, 2007 @ 11:33pm
I appreciate your quick reply (
by Rodey on Aug 18, 2007 @ 11:42pm
Rodey, in one thing you are right: this was a reactionary response. I was disappointed with the previous post mainly because it didn't touch on a lot of the more advanced concepts and what is interesting about them. Given some of the comments on this article here and over at Digg it's clear to me that the other post was well suited towards a different subset of PHPers. That being said, I don't see why this post can't compliment the other one (despite my initial intention).
by Peter Goodman on Aug 19, 2007 @ 12:01am
Nice post, very informative, I guess you can't please everyone, like that Rodey fella ...
by Eddie on Aug 19, 2007 @ 12:55am
I'm from Digg! I love some of your posts. You just got a new reader.
by Alex Forster on Aug 19, 2007 @ 3:09am
The variable composition bit will be useful!
Good article - as an experienced PHP coder not everything was either new or useful to me, but that's not to say the article won't be useful to many other people and the more people attempt to give back to the community the more there is to be had - so thanks.
On the static variable usage (which, personally, I find extremely useful!) the original assignment (where $var === null) can be put in the static declaration, such that:
function increment() {
static $count = 0;
return ++$count;
}
Just cleans up the code a bit - I don't know of any technical or logical reasons why this is different from your other method?
Cheers!
by Zelborg on Aug 19, 2007 @ 6:22am
In #3,
extract(array('a' => 'a', 'b' => 'b');
is missing a ')'.
by James on Aug 19, 2007 @ 9:02am
James, thanks, the example would have been incorrect had you not pointed that out :)
by Peter Goodman on Aug 19, 2007 @ 9:20am
Another tip is always use preg instead of ereg. It's faster and has more features
by K on Aug 19, 2007 @ 9:23am
Zelborg, you're right, that would clean it up a bit! Generally my practice for doing that if statement is that I will normally put some sort of logic in there.
Eg, lets say I want to cache an array. Initializing the static variable to an empty array would work off the bat, but then the cache wouldn't work as expected. How would I know if I've already fetched the information or not? Do I check if that array is empty? What if the initializing code returns an empty array?
For the simple examples (such as the above one) you're bang on about simplifying that function; however, as the static keyword is used for more appropriate things it's generally extremely useful to tell the difference between uninitialized (eg: NULL) and initialized (eg: an array, empty or not).
by Peter Goodman on Aug 19, 2007 @ 9:25am
Hello,
Thanks for the example on __halt_compiler(). I've came across the function when studying (and passing!) my ZCE - but never really understood its whole benefit.
Appreciated.
-aaron
To the previous poster: Do you speak English? This gentleman is not here to code your projects for you, if you are having issues with foreign language Charsets then it's something you need to research yourself. If you want your question to be answered, perhaps you should learn proper grammar so you are understood.
by Jason on Aug 19, 2007 @ 1:05pm
Strike that, i was referring to the first poster scrtadmr8
by Jason on Aug 19, 2007 @ 1:06pm
hmmm... i'm glad to see that something similar to these tricks we've already used in our projects.
by Sonic on Aug 19, 2007 @ 1:51pm
These are definitely great pointers. One question about the SPL functions you refer to, if you were to construct an object to support them does that mean that the normal method of passing attributes into an instantiated object through arguments won't work anymore? Is it one or the other, or can you use either $foo->bar or $foo['bar']?
Another thing that I'm interested in but have not been able to find anything about, is how to store an instantiated object to disk without having the overhead of serialize and deserialize? I have upgraded some framework code from a large associative array to an object with methods and properties. I used to store the array to disk by using var_export() which took a third of the time that serialize/deserialize takes to load. Is there something comparable for instantiated objects?
Mike, using magic functions to pass attributes to a class only affect attributes that the class doesn't already own. Implementing arrayaccess does not mean that attributes can't be accessed in the normal way and it also does not mean that you can't use the magic functions.
The beauty of the magic functions and arrayaccess is that they are not mutually exclusive. You can use both at the same time and you can implement them in different ways if you so choose.
The subject of storing an object persistently is much trickier. var_export() is nice for arrays, and serialize can be bulky. For storing objects, I would suggest having the class implement Serializable and serializing them (unfortunately).
However, that doesn't have to be the end-all-be-all of the problem. Can you describe what the nature of the data you want to store is, and are you storing it to transfer state between requests?
by Peter Goodman on Aug 19, 2007 @ 6:56pm
You are very wise
by Wirah on Aug 19, 2007 @ 7:40pm
__construct is nice
by rollenc on Aug 19, 2007 @ 8:32pm
Great article, I found tip #4 to be extremely useful. Even though I have been using PHP for years, I find it hard to believe myself that I have never come across/used this more extensively.
simply the most advanced PHP article i've ever seen!!!
by mamnun on Aug 20, 2007 @ 1:33am
PHP is just AWFUL. God AWFUL. It hurts it's so bad. Trust me, I have the displeasure of working with it from time to time. Meh.
by JBW on Aug 20, 2007 @ 2:46pm
JBW, in that case I suggest you take a look at my most recent post: 12 things you should dislike about php.
Otherwise in many respects I agree with you; there's a reason why my new favorite language is python ;)
by Peter Goodman on Aug 20, 2007 @ 2:50pm
Peter,
I will. I prefer Ruby myself. After years as a Java developer it just feels better. Python is nice...I gave it a shot, but Ruby is much more my style.
I spent eight years with PHP off and on, and God help me if I have to look at another line of it after this final project I'm finishing...
by JBW on Aug 20, 2007 @ 3:42pm
nothing new for me but still nice.
most of the "advanced" things here are simply new since adoption of php5 is slower then expected.
i'd also recommend everyone reading to check out zend framework for the edge in php5!
by PHANTOm on Aug 20, 2007 @ 5:05pm
Oh god, I am drooling over the Standard PHP Library.
This will keep me occupied for YEARS!
So godly.
Thank you!
LIQUID_X: if anything PHP-ish keeps you occupied for years and you're still happy, please check into the nearest mental hospital. The only way PHP can keep someone occupied for years is to weave them into a deep, tangled web of spaghetti code.
Go take a look at Ruby. Give it two weeks and I promise you'll never, ever, ever want to look at PHP code again.
PHP is an ugly, dirty hack. Nothing more.
by JBW on Aug 21, 2007 @ 7:37am
hey this is really interesting.
i have never heart preg_split oder __call
by Simon on Aug 21, 2007 @ 10:21am
Hi Peter, I'm glad to hear that with the magic functions and arrayaccess I can allow people to use $object['property'] or $object->property as they so choose.
I'm the lead (and pretty much only) developer for the PHP port of the popular Fusebox framework, originally developed for ColdFusion. Before anyone starts to scoff and snort saying how bad ColdFusion is or how bad Fusebox is, I will say that that it's becoming very popular in PHP as well, and I've received a great deal of support from other developers who have used the framework for their applications' success. My problem comes in the fact that the new version of the framework has moved to objects. CF has an application scope that persists across requests even from multiple users, so once the XML config and command files are read in and converted into the stored object it takes milliseconds for subsequent requests to access them. Previously I replicated the "application" scope by writing the complex structure to disk using var_export(). Even though the resultant file could be 800k or higher for larger projects, the structure file could be included into the beginning of the request with only a small performance hit. Now that the cached structure contains instantiated objects I can no longer use that technique and am forced to use serialize/deserialize.
Now, though the physical file is actually smaller, it takes up to 10 times longer for a large application structure to become ready for the rest of the request. Even though the new version of the framework is far superior to the previous, this overhead -- along with the fact that the array notation in their user code no longer works for accessing child members -- is causing many PHP Fusebox developers to stick with the previous version.
Sorry to take this off-topic. I'll happily move this to a private discussion if you wish to contact me at mike [at] fusebuilder [dot] net
First time I've seen this information posted online, very resourceful!
Nice article. I just have one beef, regarding number 1. The Reflection API is pretty cool, but the example you give as to why you should use it is terrible.
You say that "call_user_func_array(array('TestCallFunc', '__construct'), array('hello', 'sir'))" doesn't work, and you are right. But if you think about it for a moment, it should be obvious why.
There are three ways to call call_user_func_array:
1. When you call it with a function name as the argument it calls that function. Basically eval()ing "function_name([expanded $args])"
2. When you call it with an array of an object, and a method name, it calls the method on the object. This is like eval()ing $obj->function_name()
3. When you call it with an array of a class name, and a method name, it statically calls the method for that class (although, it should work even without the static keyword on the method, as long as the method doesn't use $this). This is like eval()ing "ClassName::method_name()"
If you think about it for a second, the example shouldn't work, since it is equivalent to "TestCallFunc::__construct()," which is meaningless. __construct is really an initializer, not a constructor, anyway; it doesn't get called until after the object is created. Your example would make sense if you replaced "__construct" with "new" but that still doesn't work because "new" is an operator in PHP, not a class method.
by Aaron Davis on Aug 23, 2007 @ 2:16pm
Mike,
Unfortunately php is not like java/cf in that state can persist across multiple requests. Although porting frameworks is nice, given that you are experiencing a huge loss in performance, I think that it's worth changing your strategy.
Aaron,
You're right, the example is rather lame. I couldn't think of anything off the bat that would demonstrate the power of the reflection api without too much code. That call user class came to mind as it is something that at times I (and I suspect others) have wanted but could not do.
Otherwise, the hint of how reflection could be used for such things as dependency injection was meant to fill the gap for more experienced programmers who--understanding introspection--could imagine how it would be done without needing written code.
by Peter Goodman on Aug 24, 2007 @ 12:54pm
What I am saying is a user has to retype entire comment for email typo crash. No proper correction rexourse -Interface design.
by mike on Aug 26, 2007 @ 9:10pm
I disagree with the use of extract(), and compact()
extract() injects all sorts of variables into the default scope
Imagine doing extract($_GET) tempting but u can guess the security implications
They make code hard to follow and are sure candidates for code obfuscation
by Quinton on Aug 30, 2007 @ 3:49am
Quinton,
Good point, extract can be very dangerous. Usually I would do it on a known associative array and pass it to an enclosed scope (in the case of a template engine).
In the case of templating, extracting request variables would be somewhat redundant and one would expect that the extract would be performed from within in a function whose role it is to solely deal with templates and nothing else. As long as the templates are separated from the code by using that function as a proxy then the default scope will be unaffected.
by Peter Goodman on Aug 30, 2007 @ 7:32am
php syntax is ugly (i have 7 years of it), it lacks a community strong focused fraework (as Rails for Ruby), not mean only one, but one clean and complete.(i use CakePHP)
Ruby syntax is very attractive, but this syntax sugar lang is slow.
i think JS2 (yes the misunderstood Javascript) as server side lang (too) is near to conquer the soul and mind of us.
taking JS seriously you will figure out the power of this lang.
taking it outside the browser will change the vision we have about it.
the problem with JS wasn't the lang itself, the problem was their incompatible implementations (read m$ IE non std crap).
this is changing now.
one strong point of php is that it's deployed everywhere, think about this factor in js.
well, my 2 php (coding style in general) cents:
// avoid nested elseif
switch (true) {
case ($a=1):
//code
break;
case ($a=2):
//code
break;
case (abs($a)==round(M_PI,2)):
//code
break;
default:
//code
break;
}
great snippets. make somethign when php 6 comes out too :)
by Judy on Dec 12, 2007 @ 10:04pm
In the first example Reflection is not actually needed and there is a much simpler way of doing this:
$class = 'TestCallFunc';
$object = new $class('hello', 'sir');
This can sometimes be useful when implementing the Factory pattern.
by Rinalds on Dec 14, 2007 @ 11:43am
Your right about that for the case where you know the arguments that you want to pass to the constructor. What I wanted to show with the Reflection example is that we dynamically construct any class given its name and an *array* holding its arguments. If, for example, instead of statically knowing the arguments 'hello' and 'sir', you had $args = array('hello', 'sir'), how would you propose that be done? ;)
by Peter Goodman on Dec 14, 2007 @ 1:50pm
In terms of practicality, this use of Reflection is an edge case; however, I still felt it cool to show that "yes it can be done."
by Peter Goodman on Dec 14, 2007 @ 1:52pm
This was a great article. Although some of the hints were a bit hackish, I could see others really coming in handy.
Hi, first off, I would like to compliment you on the very useful article you have shared with us.
Secondly, I must say I grow weary of reading the drivel posted by some people who for some apparent reason feel the need to babble on about what a load of garbage this language is and what a load of crap that language is.
I am a fairly advanced coder and I have experience developing in multiple languages like many other developers throughout the world.
I personally would like to think that a truly professional developer has the sense and intelligence to use the proper tool for the job at hand. I dont see any benefit from slamming one or the other.
I also would like to point out that not all PHP code is spaghetti code people, there is very well written and highly professional applications developed using the PHP language. And what the heck, it is the most widely used scripting language in the world is it not?
Just look at the number of high level applications that are using PHP as their base language.
Facebook, Digg, Yahoo and many many more. I wonder why that is? Do you think the developers at Yahoo or Facebook write crappy spaghetti code?
I think not.
You may say that should be using a more elegant or powerful language or something? Apparently the developers of these multi billion dollar applications used by millions of users each day feel a wee bit differently than some.
So I guess all I have left to say about this is if you dont like how PHP code is written, then dont write it that way, write it properly, and professionally. If you dont like PHP, dont use it then. But if you dont like it and have to use, dont whine about it. Do you job, collect your pay check and act like a professional not an whining elitist baby! And If you dont like th way PHP does something or how a particular function behaves, well then.... why dont you step up and fix it then instead of complaining about it. It is open source is it not?
PHP is not going away my friends, it is here to stay and it is only getting bigger and better.
Regards
by K. Therriault on Mar 22, 2008 @ 5:44pm
You know I thought Ruby was something great because it could chain functions. There are some other cool little things in here as well such as List() Extract() Compact(). That I had no idea about, thanks for this nice little list.
by ajcates on Apr 18, 2008 @ 3:42am
Add a Comment