share
Stack OverflowHidden Features of PHP?
[+175] [78] George Mauer
[2008-09-14 15:21:11]
[ php hidden-features ]
[ http://stackoverflow.com/questions/61401/hidden-features-of-php ]

I know this sounds like a point-whoring question but let me explain where I'm coming from.

Out of college I got a job at a PHP shop. I worked there for a year and a half and thought that I had learned all there was to learn about programming.

Then I got a job as a one-man internal development shop at a sizable corporation where all the work was in C#. In my commitment to the position I started reading a ton of blogs and books and quickly realized how wrong I was to think I knew everything. I learned about unit testing, dependency injection and decorator patterns, the design principle of loose coupling, the composition over inheritance debate, and so on and on and on - I am still very much absorbing it all. Needless to say my programming style has changed entirely in the last year.

Now I find myself picking up a php project doing some coding for a friend's start-up and I feel completely constrained as opposed to programming in C#. It really bothers me that all variables at a class scope have to be referred to by appending '$this->' . It annoys me that none of the IDEs that I've tried have very good intellisense and that my SimpleTest unit tests methods have to start with the word 'test'. It drives me crazy that dynamic typing keeps me from specifying implicitly which parameter type a method expects, and that you have to write a switch statement to do method overloads. I can't stand that you can't have nested namespaces and have to use the :: operator to call the base class's constructor.

Now I have no intention of starting a PHP vs C# debate, rather what I mean to say is that I'm sure there are some PHP features that I either don't know about or know about yet fail to use properly. I am set in my C# universe and having trouble seeing outside the glass bowl.

So I'm asking, what are your favorite features of PHP? What are things you can do in it that you can't or are more difficult in the .Net languages?

Broken OO paradigm? For me it's the worst "hidden" feature you discover. - knoopx
These threads are kind of funny... Because for the team I work with "hidden feature" is a code phrase meaning "bug". And you know what... Sometimes discovering a hidden feature is not necessarily a good thing... - Ganesh Shankar
@Ganesh one man's bug is another mans hidden feature... - Xeoncross
[+330] [2008-09-14 17:32:25] Kyle Cronin

Documentation. The documentation [1] gets my vote. I haven't encountered a more thorough online documentation for a programming language - everything else I have to piece together from various websites and man pages.

[1] http://www.php.net/manual/en/

(60) I agree. Being able to type www.php.net/function_name and getting a reference most of the time is great. - Allain Lalonde
(23) I agree, the php manual is more important then my IDE. - UnkwnTech
eh, I like the manual and all but it would be nicer if everything was not just global. Not to mention some of the function names are so arbitrary its sometimes hard to find what you want. - George Mauer
Most IDEs have a manual look up function. In my IDE (PhpDesigner) if you type a function name and type in (), it shows you the arguments it expects in a tooltip. If you select a function and press f1 it shows the manual page for that function in the .chm file - Click Upvote
(1) This is a great feature of PHP, but I wouldn't really call it hidden... If you've ever googled for method parameters, etc, you would end up at php.net. - John Bubriski
True; However, the question I answered was titled "What are your favorite PHP langauge features?" and the documentation certainly applies to those criteria. - Kyle Cronin
Hmm... two downvotes in two days... was it something I said? - Kyle Cronin
(27) I agree as well. The greatest thing about the manual are the user comments. I have rarely seen other documentations have those. They can contain real gems. The only downside is that IMHO they a pruned little too soon. - Sander Marechal
(5) Too bad though that user comments do not seem to make it into the actual documentation? - Arjan
I would appreciate if they organized the function reference a bit better and divided it into topics. Especially the classes related to specific databases and other outside technologies should be separated, because they're rarely used and there's a lot of 'em. - Pies
MSDN is an extensive and largely superb reference (when including the HOWTOs and guides). It shocks me that regardless, documentation is what php devs believe is the most superior feature of php. - G-Wiz
(3) @Phoexo "little bit less read-able" ??? I never understanded and will never understand MSDN, while PHP docs are easy and clear. - Maxorq
PHP's are easy and clear, no doubt about that, but MSDN is also a good source of information and will answer most of your questions. - Phoexo
The comments system is amazing; I wish Sun had this for their online Javadocs, although there is Docjar (but would be better on the Sun website due to more visitors). - Chris Dennett
this is a nice feature, but how is it at all hidden? - Wallacoloo
@wallacoloo the question I answered was titled "What are your favorite PHP langauge features?" and the documentation certainly applies to that - Kyle Cronin
(3) Disagree. The only reason the documentation is "good" is because of some of the user comments plugging all the holes in the official notes. - Rob Howard
Yeah, PHP's documentation is good because it covers most of the 9000 edge cases of each function, and even more is covered in the comments. - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
1
[+180] [2008-09-15 16:33:28] user8134

Arrays. Judging from the answers to this question I don't think people fully appreciate just how easy and useful Arrays in PHP are. PHP Arrays act as lists, maps, stacks and generic data structures all at the same time. Arrays are implemented in the language core and are used all over the place which results in good CPU cache locality. Perl and Python both use separate language constructs for lists and maps resulting in more copying and potentially confusing transformations.


(1) The advantage with Perl's approach is that we can declare our intent to have an ordered container. - jrockway
(11) PHP array elements are ordered. - user8134
(117) My initial move from PHP to C# almost killed me. In C#, arrays are just a simple structure with a static size and numeric index. In PHP, arrays are the duct tape of the universe! - Dinah
(2) Indeed, the flexibility of PHP arrays as well as the interfaces ArrayAccess and Iterator and Countable (to create a class that can be used exactly like an array) make my life so easy where as doing some tasks are harder without. - dcousineau
(1) The versatility of arrays is hard to under-estimate. Once you develop a mindset to take advantage of them, you can do some amazing things. - staticsan
(4) I also agree. When playing with Java for a Uni assignment, I was stunned at how rigid they were, no flexibility at all. Really made me appreciate just how good PHP arrays are. - Christian
You can even easily convert between arrays and objects by doing (array) $object and (object) $array. It's not recursive, but it's not difficult to write a function that is. - Pies
(1) Comparing php array to java arrays is like comparing apples with bananas. If you need fast and fixed size collections, use an array. If you need growing and easy to use collections, use a List. - whiskeysierra
(11) I'm sure php arrays are great, but 40 votes for the comment that knocks C# arrays? If a C# array doesn't fit the need, there are many options. ArrayList and generic collections are both very powerful. There are numerous types of collections for specific needs. The only actual advantage of php in this regard is that it doesn't provide any options from which a programmer must decide. You either use array or you don't have an indexable variable. - G-Wiz
(24) On the other hand, the syntax for arrays completely sucks. In many scripting languages you can create a simple 2D array like so: [[1, 2], [3, 4]], compare this to the PHP version: array(array(1, 2), array(3, 4)). - Rene Saarsoo
(2) @gWiz: agreed. Not clear why C#'s array gets dinged for not also being an ArrayList, Dict or HashTable. Just because it works that way in one language doesn't mean it should everywhere else. That said, I used to curse ASP every time I had to switch back from PHP for much the same reason. - Tom
@Tom C#'s arrays get dinged because you have to think. You just said there are 4 datatypes which are needed to cover most of the abilities of PHP's plain-ole arrays. PHP arrays just work. - smdrager
(2) You're comparing static and dynamic languages and complaining that you don't get the benefits of a dynamic language with a static language without considering the downsides to dynamic languages. I fall into the dynamic language camp and much prefer PHP's approach, but it doesn't make it The One True Way. - Tom
I'm not sure people are knocking C# arrays. I had the same problem (still do) in which that when I went from PHP to C#, I was in the mindset that arrays are truly used for everything. But in C#, the array is just an array. It was just the culture shock rather than hating on C#. - Chris Ridenour
…it's not about knocking C# arrays, but I upvoted for "In PHP, arrays are the duct tape of the universe!" - feeela
2
[+168] [2008-09-14 17:30:13] Allain Lalonde

Stream Handlers allow you to extend the "FileSystem" with logic that as far as I know is quite difficult to do in most other languages.

For example with the MS-Excel Stream handler [1] you can create a MS Excel file in the following way:

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) { 
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50),  
    array("Name" => "Popo Jijo", "Age" => 75),  
    array("Name" => "Tiny Tim", "Age" => 90)
); 

fwrite($fp, serialize($data));
fclose($fp);
[1] http://www.phpclasses.org/browse/package/1919.html

People have no idea how powerful streams are... not even me :) - Ionuț G. Stan
I believe that the KIO framework lets you do this as well, but that's only available for KDE-based desktop applications. - MiffTheFox
(30) Okay... now THIS is a wow. Thank you, thank you, thank you. - Ivan Vučica
(21) IMHO having a proper OO approach would be much more sensible than this mess with stream handlers. Yes, its cute to be able to read/write Excel files, but does it have to work like this? - Anti Veeranna
(3) Maybe so, but this approach encapsulates complexity in an interface that's common to most PHP developers... without requiring them to learn Object Oriented concepts which might be beyond them. - Allain Lalonde
(13) If you're working with Amazon S3, check out Zend_Amazon_S3, which provides a stream interface for urls like 's3://{bucket-name}/path'. - notJim
(1) Wow, I didn't know the S3 trick. Thanks notJim. - Allain Lalonde
I've used this to create a simple DSL for my view layer by just reading the PHP file, doing some string replacement and passing it trough eval(). Eg, I made it such that I can use short-tags whenever I choose to and do @->someVar so I can access view-level data. - Jasper Bekkers
not a php coder but isn't this code snippet missing closing brackets for the middle three array( lines? - rtpHarry
Thanks. Yes it was. - Allain Lalonde
Some streams are available for pop and imap too. Really killer! - Savageman
@Allain Lalonde: I don't think anybody who can't grasp the concept of OOP should be writing code of this complexity. Also, how does this method combine with other stream handlers? What if I wanted to upload that XLS file via ftp://? - Matti Virkkunen
3
[+131] [2008-09-14 17:21:29] Allain Lalonde

Magic Methods [1] are fall-through methods that get called whenever you invoke a method that doesn't exist or assign or read a property that doesn't exist, among other things.

interface AllMagicMethods {
    // accessing undefined or invisible (e.g. private) properties
    public function __get($fieldName);
    public function __set($fieldName, $value);
    public function __isset($fieldName);
    public function __unset($fieldName);

    // calling undefined or invisible (e.g. private) methods
    public function __call($funcName, $args);
    public static function __callStatic($funcName, $args); // as of PHP 5.3

    // on serialize() / unserialize()
    public function __sleep();
    public function __wakeup();

    // conversion to string (e.g. with (string) $obj, echo $obj, strlen($obj), ...)
    public function __toString();

    // calling the object like a function (e.g. $obj($arg, $arg2))
    public function __invoke($arguments, $...);

    // called on var_export()
    public static function __set_state($array);
}

A C++ developer here might notice, that PHP allows overloading some operators, e.g. () or (string). Actually PHP allows overloading even more, for example the [] operator ( ArrayAccess [2]), the foreach language construct ( Iterator [3] and IteratorAggregate [4]) and the count function ( Countable [5]).

[1] http://www.php.net/manual/en/language.oop5.magic.php
[2] http://www.php.net/manual/en/class.arrayaccess.php
[3] http://www.php.net/manual/en/class.iterator.php
[4] http://www.php.net/manual/en/class.iteratoraggregate.php
[5] http://www.php.net/manual/en/class.countable.php

(4) As useful example of what can be achieved with magic methods goto phpcodetips.blogspot.com/2008/07/domain-model-validation.html - grom
(6) Disagree. This is far weaker than similar facilities in Smalltalk, Ruby & Python (and presumably it was copied from one of these) - finnw
(34) The fact that PHP's implementation of this functionality is weaker than those other languages, doesn't make it any less useful in PHP. - Allain Lalonde
(2) __call() is great in frameworks with map domain.com/controller/method/ - alex
(7) Magic methods are also slow as hell. Use them carefully. - Alex Weinstein
Slow compared to what: garfieldtech.com/blog/magic-benchmarks yes, it's slower but not appreciably so. The pipeline will play a larger role than the magic methods unless you're operating under very large loads. - Allain Lalonde
Useful for view-level logic and implementing Mixins as known in Ruby, for example. - Jasper Bekkers
(1) Anyone else think that magic methods are fantastically dangerous? They don't autocomplete in your IDE of choice, unless you know there's some magic then stepping through code execution by eyeball is impossible, you can end up using them by accident instead of a similarly-named non-magic method... - sanbikinoraion
This seems similar in effect to forward invocation in Objective-C. - G-Wiz
And since php 5.3 "__invoke" is added to the list of magic functions. - Bob Fanger
I updated the list to include all magic methods and have added a paragraph about other methods of overloading functionality. - NikiC
What language that allows operator overloading does not allow overloading of those operators? - Billy ONeal
4
[+95] [2008-11-01 07:42:37] Dean Rather

The standard class is a neat container. I only learned about it recently.

Instead of using an array to hold serveral attributes

$person = array();
$person['name'] = 'bob';
$person['age'] = 5;

You can use a standard class

$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

This is particularly helpful when accessing these variables in a string

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

(43) "{$person['name']} is {$person['age']} years old" works. - porneL
You should post that as a hidden feature, I'd vote it up :) - Dean Rather
(27) "person[name] is $person[age] years old" will also work... No quotes, no braces :) - majelbstoat
I didn't know that one. It doesn't complain that it has to assume you're not using undefined constants? - Dean Rather
thanks, this was helpful - Click Upvote
Makes it very Javascript-y :) - thomasrutter
@Dean if you don't use curly braces, no it doesn't complain. The [ has to immediately follow the variable name, then its contents are interpreted as a string. - thomasrutter
Wow! That's neato! - MiseryIndex
(16) $string = sprintf("%s is %d years old.", $person['name'], $person['age']); - Daniel Sloof
(60) While we're on the subject: (object)array("name" => 'bob', 'age' => 5) - Annika Backstrom
(30) @majelbstoat: Taking out the quotes would slow the script down because the PHP interpreter will look to see if 'name' and 'age' have been set with define(...). It's also a bad practice considering it'd be possible to totally flip the keys that are accessed in each case: define('age','name'); define('name','age'); - brianreavis
Don't care about performance, readability is (way!) more important. - whiskeysierra
Both using arrays AND standard class is helpful for different things. - Talvi Watia
(4) @Willi Schönborn: sure, the performance aspect may not really matter, but considering the fact that an E_NOTICE is thrown every time PHP encounters one of those, it's just plain sloppy. - Frank Farmer
(1) @Adam Backstrom whoa, that is an object literal in PHP! You've just blown my mind. - thomasrutter
(6) @brianreavis and @Frank Farmer that's not the case. With no curly braces inside the string, PHP treats what's in the braces as literal. eg: "$person[name]" is equivalent to "{$person['name']}" - PHP won't consider name to refer to a constant in either case. See Types -> Strings, under "Variable parsing" in the PHP manual. - thomasrutter
don't use $person[name]... if you set error_reporting to E_ALL, you will see that the compiler throws a notice. Always quote string array keys: $person['name'] - Harold1983-
I can't begin to fathom why @brianreavis's comment has 23 upvotes even though he's fundamentally misunderstood variable interpolation in strings... - Matti Virkkunen
5
[+90] [2009-08-06 19:59:58] Philippe Gerber

Include files can have a return value you can assign to a variable.

// config.php
return array(
    'db' => array(
        'host' => 'example.org',
        'user' => 'usr',
        // ...
    ),
    // ...
);

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org

(12) +1 this was news to me. Not sure how i can really use this in real life, but it made my head turn... ;) - Peter Lindqvist
@Peter VERY useful for db->localhost exception error handling. - Talvi Watia
It's convenient for setting up a quick-and-dirty config file. - Frank Farmer
Why do you return this array? If an included file contains an array it's usable at the include immediately. - fabrik
(5) @fabrik because it would be global variable and available in the whole main scope. That's quite unpleasant, this is way better. - Mikulas Dite
i worked on a project in Yii framework and that project have config file in which array was returned like this, now i understand why file was like this. - oditiwebs.com
6
[+83] [2009-02-09 01:51:15] Pies

You can take advantage of the fact that the or operator has lower precedence than = to do this:

$page = (int) @$_GET['page'] 
  or $page = 1;

If the value of the first assignment evaluates to true, the second assignment is ignored. Another example:

$record = get_record($id) 
  or throw new Exception("...");

(7) I'm not quite convinced of this I think; even though it seems not to be error prone it's counter-intuitive, and that in itself may promote errors. - thomasrutter
Then again, who am I to talk. I use the ternary operator a fair bit, and yet some people feel that it's an abomination! - thomasrutter
@thomasrutter: How would you write the first example without using 'or'? - Pies
(14) @Pies: one way is the following, quite messy code to be honest: $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; // Advantage of this is no error suppression is required. - DisgruntledGoat
(3) on second thoughts, since you're looking for an integer you could use instead: $page = is_int($_GET['page']) ? $_GET['page'] : 1; - DisgruntledGoat
The point of doing it my way is simply that it's shorter and might be easier to read. Obviously you can do the same thing in more code. Mostly I wanted to avoid writing $_GET['page'] twice. - Pies
(4) It's worth noting that the code after or will execute if the code before or results in the numeric value 0. So semantically it may be less likely with something like $_GET['page'], but obviously the circumstance may arise and it's good to watch out for. - eyelidlessness
(3) It's also worth noting that the or operator is a lower-precedent version of the || operator. Also, +1 because this is highly expressive and I often forget it's possible. It should be used more often, and it's absolutely clear in what it does. I don't know about how "real males" code though, so I can't comment on that. - eyelidlessness
(3) Real men like strong typing. - Pies
Personally, I hesitate to use or because I don't trust everyone I work with will always be cognizant of the difference between or and || - Frank Farmer
Wow, I wish JavaScript allows that... In JS, throw is a statement. - SHiNKiROU
It should have been called then - JeroenEijkhof
@DisgruntledGoat, $_GET['page'] can never be an int, unless you modify $_GET in your PHP code. - Ionuț G. Stan
@Ionuț: Yeah I guess I meant is_numeric since that checks if it's a numeric string. - DisgruntledGoat
@DisgruntledGoat, yup, that will do. - Ionuț G. Stan
(2) -1 BAD example for a GREAT feature! - NikiC
using 'or throw' doesn't work, you'll get an unexcepted T_THROW error. - Harold1983-
$page = getPage($_POST["page"]) or GTFO(); - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
I feel something is added to my brain luggage every time a suppressor is used... + It is better to 404 for an URL ...&page=<something_not_valid>, rather than silently swallowing it. - Halil Özgür
@HalilÖzgür I think that reading from $_GET is one of the legitimate uses of error suppression, but to each his own. You could just as well create a function for it. - Pies
Everybody here seems to have forgotten this gem: mysql_connect(*) or die() - Tim Gostony
7
[+80] [2008-10-02 18:31:32] Wimmer

__autoload() [1] (class-) files aided by set_include_path().

In PHP5 it is now unnecessary to specify long lists of "include_once" statements when doing decent OOP.

Just define a small set of directory in which class-library files are sanely structured, and set the auto include path:

set_include_path(get_include_path() . PATH_SEPARATOR . '../libs/');`

Now the __autoload() routine:

function __autoload($classname) {
    // every class is stored in a file "libs/classname.class.php"

    // note: temporary alter error_reporting to prevent WARNINGS
    // Do not suppress errors with a @ - syntax errors will fail silently!

    include_once($classname . '.class.php');
}

Now PHP will automagically include the needed files on-demand, conserving parsing time and memory.

[1] http://php.net/manual/de/language.oop5.autoload.php

is spl_autoload_register() better to use? - alex
(19) Of course! __autoload() is PHP4 but spl_autoload_register() is a non-destructive "daisy-chaining" of autoloading methods. - Wimmer
(3) A handy feature, but the one caveat is when you find an instance of a given class, it makes it a little more difficult to hunt down the location of a class file. Explicitly defining includes at the top gives you a finite list of involved classes and their exact location. - Cory House
It's a nice feature, but only to get around the situation of not having code precompiled, so it doesn't know where the class is going to be. Big downside of this is that you can't have 2 classes with the same name, even if they are in different namespaces. - Kibbee
@Cory: Just have __autoload keep a list of classes loaded and the files it has loaded them from. - Jasper Bekkers
@Jasper & @Cory: You could also use php.net/get_included_files. - mcrumley
(3) Please have a look at the PSR-0 propsal from the PHP Standards Working Group (featuring developers of ZF, Symfony, Doctrine, CakePHP, Solar, etc.) when implementing autoloading: groups.google.com/group/php-standards/web/psr-0-final-proposal - Philippe Gerber
8
[+76] [2008-09-15 12:51:35] Jrgns

Variable variables and functions without a doubt!

$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!

The same concept applies to object parameters ($some_object->$some_variable);

Very, very nice. Make's coding with loops and patterns very easy, and it's faster and more under control than eval (Thanx @Ross & @Joshi Spawnbrood!).t


(3) Love these! Took minutes to boggle me, years to master. - Abyss Knight
Faster than eval(). - Ross
PHP Fatal error: Call to undefined function foobar!(); Drop the $$ in front of foo(); - David
@David: I fixed it and added another call... :) - Jrgns
Also say more under controll than "eval()" !! - Joshi Spawnbrood
stackoverflow.com/questions/1003605/… << Related question I posted last week - sjobe
(111) variable variables are actually making the code less readable and more prone to errors. - Elzo Valugi
(1) Okay... okay... this is sick. As Elzo said, less readable, messier, thus bad. This is NOT Perl. - Ivan Vučica
(2) With more flexibility, you will have more complexity. But also more flexibility :) - Jrgns
(8) And people really use this? Man i'd hate to read these sources. - Gary Willoughby
(27) Variable variables are one of the worst features PHP offers. - notJim
(1) often messy, but in very few cases really good help - dusoft
(10) 9 Out of 10 times variable variables are better replaced with arrays so you have all the data in one place, you can iterate over it et cetera. Only in some very specific circumstances might they be useful. - Jasper Bekkers
(7) Please dont make newbies use that "feature". - whiskeysierra
Variable variables are essentially double pointers. Variable functions functions are just function pointers. The concepts has been around for years since C. - Alex Weinstein
@Alex - Yeah, except in PHP, newbies may use it and accept user input, which in turn causes me having to help these f'ers. - Tor Valamo
call_user_func() is another possible substitute for some uses of variable functions. - Frank Farmer
Please at a minimum write ${$a}. Just so the rest of us knows that something is going on, and the two $$ are not just collapsed into one. - Thomas Ahle
I don't know much about PHP, but implementing references (or using them if they already exist) would be way better than doing it this way. - Wallacoloo
What on earth can you use this for? Could someone explain it? - Emil
@Emil, calling a template whose name is stored in a database would be one example. - zzzzBov
Just because it's better (i.e: not as bad as) eval, doesn't change the fact that it's complete bullshit. - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
9
[+76] [2008-09-16 13:39:09] Chris Ridenour

Easiness. The greatest feature is how easy it is for new developers to sit down and write "working" scripts and understand the code.

The worst feature is how easy it is for new developers to sit down and write "working" scripts and think they understand the code.

The openness of the community surrounding PHP and the massive amounts of PHP projects available as open-source is a lot less intimidating for someone entering the development world and like you, can be a stepping stone into more mature languages.

I won't debate the technical things as many before me have but if you look at PHP as a community rather than a web language, a community that clearly embraced you when you started developing, the benefits really speak for themselves.


(53) For me PHP was the gateway drug into programming. - Ólafur Waage
Me too. I've been around the block with many other languages and I still find myself coming back to and enjoying PHP. - robsymonds
(3) #phpc is your friendly, neighborhood dealer! - dcousineau
(3) Definitely a good comment. Python was my first language and it was awesome, but the lack of projects I felt capable of understanding did create a barrier. With PHP I can look up pretty much anything on the documentation and figure it out...the resources available on the web are amazing. - dscher
10
[+68] [2009-07-09 12:24:41] TheBrain

You can use functions with a undefined number of arguments using the func_get_args().

<?php

function test() {

    $args = func_get_args();
    echo $args[2]; // will print 'd'
    echo $args[1]; // will print 3
}

test(1,3,'d',4);

?>

(1) Was just about to post this. Sort of like the arguments property in JS functions. - alex
11
[+67] [2009-05-20 06:07:15] zombat

I love remote files [1]. For web development, this kind of feature is exceptionally useful.

Need to work with the contents of a web page? A simple

$fp = fopen('http://example.com');

and you've got a file handle ready to go, just like any other normal file.

Or how about reading a remote file or web page directly in to a string?

$str = file_get_contents('http://example.com/file');

The usefulness of this particular method is hard to overstate.

Want to analyze a remote image? How about doing it via FTP?

$imageInfo = getimagesize('ftp://user:password@ftp.example.com/image/name.jpg');

Almost any PHP function that works with files can work with a remote file. You can even include() or require() code files remotely this way.

[1] http://www.php.net/manual/en/features.remote-files.php

(2) This is so nice! To do this in for example Java you need to include a gazillion jar files and than write a lot of boilerplate code. - Kimble
(16) "You can even include() or require() code files remotely this way." Of course, include()ing a file on a server you don't control is a terrible, terrible idea. - Frank Farmer
(4) @Frank - yes, well, one would presume that you would be including code from a server you did control. - zombat
(1) Point being, remote file inclusion is a common PHP security issue: en.wikipedia.org/wiki/Remote_File_Inclusion#PHP . - Frank Farmer
I don't really get why anyone would need to include remote PHP files. - Halil Özgür
12
[+63] [2009-03-20 09:51:16] thomasrutter

strtr() [1]

It's extremely fast, so much that you would be amazed. Internally it probably uses some crazy b-tree type structure to arrange your matches by their common prefixes. I use it with over 200 find and replace strings and it still goes through 1MB in less than 100ms. For all but trivially small strings strtr() is even significantly faster than strtolower() at doing the exact same thing, even taking character set into account. You could probably write an entire parser using successive strtr calls and it'd be faster than the usual regular expression match, figure out token type, output this or that, next regular expression kind of thing.

I was writing a text normaliser for splitting text into words, lowercasing, removing punctuation etc and strtr was my Swiss army knife, it beat the pants off regular expressions or even str_replace().

[1] http://au2.php.net/strtr

(1) That's quite nifty, I hadn't noticed what strtr() did before. - Robert K
(1) It's probably faster because it does single character replacements. - staticsan
(10) strtr() does not just do single-character replacements. It can replace arbitrary-length substrings with other arbitrary-length substrings, and it still seems really fast. - thomasrutter
(1) You mentioned it was faster than strtolower in some cases, can you prove it? I did a small benchmark and found it to be false. - The Pixel Developer
(1) I found that on small strings of say 80 characters it was slower than strtolower, and on large strings of say 1MB it was faster. There's probably some fixed cost type overhead each time it's called. I was simply using strtr($this->string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); The string I was operating on was some typical English text ("The quick brown fox", that sort of thing). - thomasrutter
I just read this post and then did some Google searching and found: simplemachines.org/community/index.php?topic=175031.0 Any idea which one is right? - Flipper
When I did testing, I found strtr to be /much/ faster for more complex replacement sets on long strings of say, 100kB in length or more. For short strings of say 80 bytes or less, I found str_replace to be much faster. I did my testing around two years ago however and I'm not sure if it's still true. I'd be surprised if strtr performance had regressed for long strings though. I believe that its performance came from doing prefix indexing before each invocation which would slow it down on short strings. - thomasrutter
13
[+61] [2008-09-22 09:39:15] Armin Ronacher

One not so well known feature of PHP is extract() [1], a function that unpacks an associative array into the local namespace. This probably exists for the autoglobal abormination but is very useful for templating:

function render_template($template_name, $context, $as_string=false)
{
    extract($context);
    if ($as_string)
        ob_start();
    include TEMPLATE_DIR . '/' . $template_name;
    if ($as_string)
        return ob_get_clean();
}

Now you can use render_template('index.html', array('foo' => 'bar')) and only $foo with the value "bar" appears in the template.

[1] http://php.net/manual/en/function.extract.php

and with EXTR_IF_EXISTS you get to set default values before the extract - Ken
(15) I was going to get angry at you for suggesting extract() in any way was a good feature. But I guess that use of it is pretty handy. I suppose it's the one time I've seen it used where it's a good idea! - thomasrutter
(5) extract() makes it dead simple to roll your own extremely light weight templating system. +1 - Dinah
(14) Its inverse, compact(), is nice as well: $a = 1; $b = 2; compact('a', 'b'); // == array('a' => $a, 'b' => $b) - Annika Backstrom
(2) Yes, that's probably the only really good use of extract(). - staticsan
Zend Framework uses extract() a lot in their view helpers. - zachleat
(4) I would suggest not using common words as function argument names in this case, since the $context from which you extract() could contain values at the 'as_string' or 'template_name' indexes. Using EXTR_SKIP is acceptable, but only moves the problem elsewhere (i.e. if the template is expecting an $as_string it'll get the incorrect value for it.) - Pies
(1) extract() is evil! Almost same evil like eval() is. There is nothing worse than trying to understand and debug code using extract() and compact() in almost every function. You never know where the variable came from. - Petr Peller
(1) I think extract() and compact() have their uses and can be very powerful when used in the right context. extract() is fantastic for making templating systems and compact is great for quickly building hash arrays. - Mark Story
Other than $as_string, this is nearly the same as my little renderView function! - Halil Özgür
14
[+52] [2009-06-22 11:52:18] Darren Newton

Range() [1] isn't hidden per se, but I still see a lot of people iterating with:

for ($i=0; $i < $x; $i++) { 
    // code...
}

when they could be using:

foreach (range(0, 12) as $number) {
    // ...
}

And you can do simple things like

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}
[1] http://us.php.net/manual/en/function.range.php

(3) you can do foreach ($array as $key=>$value) {} which is even simpler. - SilentGhost
(15) It might be a micro-optimization, but it's worth noting that for and while are much faster and less memory-intensive than foreach. - JAL
this is NOT how range() should be ever used! - Newbie
(3) You should try Python. It's as simple as "for i in range(12)", or you can use the more efficient xrange. - Wallacoloo
I have been, that's kind of where I got the idea. I started using Python to solve Project Euler questions and its been good. - Darren Newton
(2) @SilentGhost: you'd still need an array to start with, which isn't always the case. @Newbie: elaborate please? - Alec
FYI, foreach can be as fast if not faster than for under certain circumstances in PHP 5.3. - wilmoore
(3) @Newbie, how come? - David Thomas
@SilentGhost this is what i use. Whenever i go over to java i always have to look up how to use foreach in there as well. It like foreach 10x better than a for loop. For loops are so 1970s. - Matt
(1) @flexxy, appartently, it's NOT. Consider this: phpbench.com scroll down to Read Loop. - Buddy
(1) @Buddy And then, check out the modify example which states "Proof in this example shows how functionally murderous the foreach() loop can be.". - JAL
15
[+44] [2008-09-14 20:15:51] VolkerK

PHP enabled webspace is usually less expensive than something with (asp).net. You might call that a feature ;-)


(3) a feature indeed... - George Mauer
(3) It's also much cheaper to set up multiple servers if you don't have to pay for Windows Server on every one. - MiffTheFox
(4) Only place I know of where Windows is cost effective is at a University that gets STEEEEP discounts on the server software in as much as it is cheaper for my dept to buy 100 copies of windows than it is to train our admins on linux (which partially makes me sad but their windows setup is clean and well setup). - dcousineau
(4) For now, but you have to make the switch only once, while you'll have to buy new licences sooner or later... - e-satis
16
[+42] [2009-01-11 07:25:39] Lucacri

One nice feature of PHP is the CLI. It's not so "promoted" in the documentation but if you need routine scripts / console apps, using cron + php cli is really fast to develop!


(4) And the php liveterminal. - Thomas Ahle
I should really look into this, I have several cron jobs that fetch a PHP script through wget http://example.com... - DisgruntledGoat
CLI is also an excellent way to spot-debug, as warnings/errors will show without you having to change your error reporting preferences. - Glacials
17
[+42] [2009-06-21 22:29:09] dcousineau

The static keyword is useful outside of a OOP standpoint. You can quickly and easily implement 'memoization' or function caching with something as simple as:

<?php
function foo($arg1)
{
    static $cache;

    if( !isset($cache[md5($arg1)]) )
    {
        // Do the work here
        $cache[md5($arg1)] = $results;
    }

    return $cache[md5($arg1)];
}
?>

The static keyword creates a variable that persists only within the scope of that function past the execution. This technique is great for functions that hit the database like get_all_books_by_id(...) or get_all_categories(...) that you would call more than once during a page load.

Caveat: Make sure you find out the best way to make a key for your hash, in just about every circumstance the md5(...) above is NOT a good decision (speed and output length issues), I used it for illustrative purposes. sprintf('%u', crc32(...)) or spl_object_hash(...) may be much better depending on the context.


(7) Just a copied feature from C/C++ - GetFree
(1) +1, but it's really strange and counter-intuitive. - whiskeysierra
(2) @GetFree I don't think anyone would deny that almost all of PHP has been copied from C, C++, Perl, etc. - Frank Farmer
(1) Copying is the best thing that can be done. - NikiC
(1) Bad PHP. It's always copying features from others. It should write everything from scratch instead! (In case of the slightest possibility of this being taken seriously: I'm joking) - Halil Özgür
18
[+40] [2008-10-06 11:11:23] e-satis

Then "and print" trick

<?php $flag and print "Blah" ?>

Will echo Blah if $flag is true. DOES NOT WORK WITH ECHO.

This is very handy in template and replace the ? : that are not really easy to read.


(24) I myself find the ternary operator much more obvious than exploiting the evaluation short-cirtcuit of a logical and. - Vicent Marti
(26) Actually that's the same number of characters as <?php if($flag) print "Blah" - too much php
(3) Parenthesis are not as easy to type as "and", especially on my bloody french keyboard ;-) - e-satis
Did not know this before. - Charlie Somerville
(2) This is shorter, assuming you have shorttags enabled: <?=$flag?'blah':''?>. Actually without shorttags it's still shorter. - DisgruntledGoat
(7) @all comments - This isn't about how short you can get it! It's about readability and ease of use for template people, who sometimes are not even programmers. - Tor Valamo
(6) I would comment that the if () statement is easier and more readable. It's certainly easier for me to get my head around than exploiting essentially a side effect of the 'and' operator in PHP, where it's easy to make a mistake (or look like it's a mistake when you read the code later). For instance, as stated this won't work the way you want with 'echo'. With if () there aren't gotchas like this. - thomasrutter
(1) print is a function, echo is a statement -- hence the reason echo won't work. - Walt Stoneburner
if... version doesn't make me think. - Halil Özgür
19
[+37] [2009-05-01 08:20:02] monk-e-boy

You can use minus character in variable names like this:

class style
{
  ....
  function set_bg_colour($c)
  {
    $this->{'background-color'} = $c;
  }
}

Why use it? No idea: maybe for a CSS model? Or some weird JSON you need to output. It's an odd feature :)


(2) Does that work with method names? Could be useful for frameworks which use a router and I want domain.com/something-with-minuses/view/ - alex
(6) The curly braces allow you to access object properites that have dashes, dots, and other non-alphanumeric entities. One reason to use it is when dealing with xml, where the entity names can be dotted like in NITF/NewsML <body.content>. If you use SimpleXML, you would access it like this $item->DataContent->body->{'body.content'}. - Jesse Kochis
(2) PHP variables can take any characters when used that way, even spaces and newlines. - Newbie
This would be very useful when using in SimpleXML... awesome. Thanks for sharing. - KyleFarris
20
[+34] [2009-03-20 10:50:23] jamolkhon

Probably not many know that it is possible to specify constant "variables" as default values for function parameters:

function myFunc($param1, $param2 = MY_CONST)
{
//code...
}

Strings can be used as if they were arrays:

$str = 'hell o World';
echo $str; //outputs: "hell o World"

$str[0] = 'H';
echo $str; //outputs: "Hell o World"

$str[4] = null;
echo $str; //outputs: "Hello World"

(3) That last one is nifty. Though I have no idea when it would be better than some other method of removing a character. +1 nontheless - George Mauer
(3) It's probably more efficient than calling a function to do it. Strings are normally stored contiguously in memory, so getting to $str[4] is trivial. Storing strings as arrays of characters is common to most languages that derive from C. - sjobe
(1) You don't have to use a defined constant as a default value. The following is also perfectly valid: function foot($param1, $default = array('key'=>'value'), $default_s = 'String', $default_i = 10, $default_b = false). However you are correct in noting you can't use a variable as a default argument. - dcousineau
@dcousineau Your example is perfectly valid since array() is not a function but a language construct. Function calls are not allowed as default values for arguments. - jamolkhon
you can also access a string char like this: $a_char=$a_string{2} - Felipe Almeida
(4) Be careful with treating strings as arrays if you have multi-byte strings (foreign languages, etc.) - philfreo
21
[+34] [2009-06-22 19:52:46] Pablo Livardo

HEREDOC syntax is my favourite hidden feature. Always difficult to find as you can't Google for <<< but it stops you having to escape large chunks of HTML and still allows you to drop variables into the stream.

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;

(6) If only my editor didn't syntax-highlight it as a string. - eyelidlessness
(2) HEREDOC is my favorite way to build and use SQL statements. - bdl
(11) Note: the closing EOM; cannot be indented. - micahwittman
+1 for a new way to create obscuration. - Talvi Watia
Good, but pointless if you use templates. Plus it gets in the way of proper indentation. - Manos Dilaverakis
(7) Dear god, that is the ugliest piece of code I have ever seen. If you're using HEREDOC's, then you haven't separated presentation from logic. - Lotus Notes
@Byron: You don't have to use it for presentation, it can be used for any string. See the comment from bdl. - tomp
@bdl: I've used heredocs for SQL statements, but stored procedures tend to be more maintainable, in my opinion. - Joey Adams
It would be much better to separate HTML, Javascript from PHP using MVC pattern. ) - daGrevis
22
[+33] [2009-06-21 23:55:02] artlung

The single most useful thing about PHP code is that if I don't quite understand a function I see I can look it up by using a browser and typing:

http://php.net/function

Last month I saw the "range" function in some code. It's one of the hundreds of functions I'd managed to never use but turn out to be really useful:

http://php.net/range

That url is an alias for http://us2.php.net/manual/en/function.range.php. That simple idea, of mapping functions and keywords to urls, is awesome.

I wish other languages, frameworks, databases, operating systems has as simple a mechanism for looking up documentation.


(1) I use this all the time and its pretty damn awesome. - Sam152
(5) range() can be useful for foreach( range(1, 10) as $i) { }; - alex
@alex yeah, i like that construction too. more elegant than a for loop. - artlung
If you have FireFox; just type PHP function in the address bar it will do a Google 'I'm feeling lucky' search and you almost always end up on the right php documentation page. - Kolky
23
[+30] [2009-06-21 02:24:00] Sam152

Fast block comments

/*
    die('You shall not pass!');
//*/


//*
    die('You shall not pass!');
//*/

These comments allow you to toggle if a code block is commented with one character.


(3) That's one of my favorite tricks I just discovered for myself to speed up development. - Alex S
(14) This isn't really specific to PHP. This works in any language that supports // ... line comments and /* ... */ block comments. - Jordan Ryan Moore
any code cleanup utilities end up hating you for using this... ;) - Talvi Watia
(3) I've also used /** / before and /**/ after. You can toggle the block by removing and adding the space in the first. This has an added benefit of working with CSS (and other languages that do not support // ... comments). - kingjeffrey
FWIW, link to the original article aleembawany.com/2009/01/27/lazy-block-comment-trick - aleemb
@aleemb, refrain from making any further edits to this question. - Sam152
24
[+29] [2009-06-21 22:43:32] MSpreij

My list.. most of them fall more under the "hidden features" than the "favorite features" (I hope!), and not all are useful, but .. yeah.

// swap values. any number of vars works, obviously  
list($a, $b) = array($b, $a);

// nested list() calls "fill" variables from multidim arrays:  
$arr = array(  
  array('aaaa', 'bbb'),  
  array('cc', 'd')  
);  
list(list($a, $b), list($c, $d)) = $arr;  
echo "$a $b $c $d"; // -> aaaa bbb cc d  

// list() values to arrays  
while (list($arr1[], $arr2[], $arr3[]) = mysql_fetch_row($res)) { .. }  
// or get columns from a matrix  
foreach($data as $row) list($col_1[], $col_2[], $col_3[]) = $row;

// abusing the ternary operator to set other variables as a side effect:  
$foo = $condition ? 'Yes' . (($bar = 'right') && false) : 'No' . (($bar = 'left') && false);  
// boolean False cast to string for concatenation becomes an empty string ''.  
// you can also use list() but that's so boring ;-)  
list($foo, $bar) = $condition ? array('Yes', 'right') : array('No', 'left');

You can nest ternary operators too, comes in handy sometimes.

// the strings' "Complex syntax" allows for *weird* stuff.  
// given $i = 3, if $custom is true, set $foo to $P['size3'], else to $C['size3']:  
$foo = ${$custom?'P':'C'}['size'.$i];  
$foo = $custom?$P['size'.$i]:$C['size'.$i]; // does the same, but it's too long ;-)  
// similarly, splitting an array $all_rows into two arrays $data0 and $data1 based  
// on some field 'active' in the sub-arrays:  
foreach ($all_rows as $row) ${'data'.($row['active']?1:0)}[] = $row;

// slight adaption from another answer here, I had to try out what else you could  
// abuse as variable names.. turns out, way too much...  
$string = 'f.> <!-? o+';  
${$string} = 'asdfasf';  
echo ${$string}; // -> 'asdfasf'  
echo $GLOBALS['f.> <!-? o+']; // -> 'asdfasf'  
// (don't do this. srsly.)

${''} = 456;  
echo ${''}; // -> 456  
echo $GLOBALS['']; // -> 456  
// I have no idea.  

Right, I'll stop for now :-)


Hmm, it's been a while..

// just discovered you can comment the hell out of php:
$q/* snarf */=/* quux */$_GET/* foo */[/* bar */'q'/* bazz */]/* yadda */;

So, just discovered you can pass any string as a method name IF you enclose it with curly brackets. You can't define any string as a method alas, but you can catch them with __call(), and process them further as needed. Hmmm....

class foo {
  function __call($func, $args) {
    eval ($func);
  }
}

$x = new foo;
$x->{'foreach(range(1, 10) as $i) {echo $i."\n";}'}();

Found this little gem in Reddit comments:

$foo = 'abcde';
$strlen = 'strlen';
echo "$foo is {$strlen($foo)} characters long."; // "abcde is 5 characters long."

You can't call functions inside {} directly like this, but you can use variables-holding-the-function-name and call those! (*and* you can use variable variables on it, too)


(2) Please don't overuse the ternary comparison operator; this leads to code obfuscation. - staticsan
(35) You win the "writing illegible code" prize for the day. - fiXedd
(3) +1 for cleverness - eyelidlessness
-1 for un-readability - whiskeysierra
(9) I would kill you. - Eric Lamb
Wow. That could totally hose your $GLOBALS list. Bad practice. Seriously. - Talvi Watia
(2) Hence the "// (don't do this. srsly.)". People, don't worry, I was just seeing what else could be done - I don't actually use most of the above in my production code.. Yes, most of it is illegible, and un-readable, and obfuscated. Please don't kill me. ps. I appreciate the cleverness upvote. - MSpreij
Is there an obfuscated PHP contest yet? - Lotus Notes
Well, trick with swap - impressive and useful, thanks. - OZ_
(1) ${''} = 456; hahaha.... quite the abuse. - Skurmedel
i am sorry, i just have only one up vote :-( - Kowser
+1 for ${''} = 456;. Finally a completely anonymous variable. - Halil Özgür
"Abuse" used correctly in your post in every sense. - Tim Gostony
25
[+26] [2008-09-14 17:51:38] MattBelanger

Array manipulation.
Tons of tools for working with and manipulating arrays. It may not be unique to PHP, but I've never worked with a language that made it so easy.


like what for example? It seems to me like the functions are all awkwardly named and positioned in the global namespace. Plus I can't think of anything thats not just as easy in another language except for maybe $arr[] = $newvalue for adding values - thats cool - George Mauer
(8) Well, the PHP array is a datastructure that can be used easily as a stack, queue, deque, list, hashtable, etc. It's pretty flexible indeed for most common needs, without resorting to anything else but array_* functions. - Camilo Díaz Repka
(6) Python does arrays (as lists and tuples) much better than PHP does. - too much php
Any language does array better than PHP. I miss [] literals so much that it driving me crazy. - vava
PHP's array functions are wonderful. I also love Ruby's. - micmoo
26
[+26] [2008-09-22 09:47:02] Andrew Taylor

I'm a bit like you, I've coded PHP for over 8 years. I had to take a .NET/C# course about a year ago and I really enjoyed the C# language (hated ASP.NET) but it made me a better PHP developer.

PHP as a language is pretty poor, but, I'm extremely quick with it and the LAMP stack is awesome. The end product far outweighs the sum of the parts.

That said, in answer to your question:

http://uk.php.net/SPL

I love the SPL, the collection class in C# was something that I liked as soon as I started with it. Now I can have my cake and eat it.

Andrew


(13) +1 for "PHP as a language is pretty poor" - whiskeysierra
27
[+24] [2009-06-22 00:39:06] staticsan

I'm a little surprised no-one has mentioned it yet, but one of my favourite tricks with arrays is using the plus operator. It is a little bit like array_merge() but a little simpler. I've found it's usually what I want. In effect, it takes all the entries in the RHS and makes them appear in a copy of the LHS, overwriting as necessary (i.e. it's non-commutative). Very useful for starting with a "default" array and adding some real values all in one hit, whilst leaving default values in place for values not provided.

Code sample requested:

// Set the normal defaults.
$control_defaults = array( 'type' => 'text', 'size' => 30 );

// ... many lines later ...

$control_5 = $control_defaults + array( 'name' => 'surname', 'size' => 40 );
// This is the same as:
// $control_5 = array( 'type' => 'text', 'name' => 'surname', 'size' => 40 );

Nice. Love the avatar, by the way. - Don Kirkby
Code sample would be nice to have. - z-boss
$defaults should be $control_defaults - diEcho
D'oh. Code sample error fixed. - staticsan
(3) I think it's not as clear as array_merge when you have a lot of code to maintain. At least, when you use, the array_merge function, it's evident that you're dealing with arrays. - Sylvain
And that fact that you're doing ... + array( ... isn't enough to point this out? :-) - staticsan
What version of PHP do you need for this? - Lotus Notes
I know it works in PHP 4. - staticsan
This is a great feature and it should be noted that the array on the "right" side of the "+" will not over-write existing keys of the array to the "left" side of the "+". - wilmoore
Actually @wilmmore, it will. That's the very feature which makes it so useful. - staticsan
I think that elements found in the left hand array are those that remain, i.e., are not overwritten by those on the right. So i think size would still be 30. - BDuelz
If you are using this as if it is array_merge, you are doing it wrong: "The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored." php.net/manual/en/language.operators.array.php vs php.net/manual/en/function.array-merge.php - Halil Özgür
28
[+21] [2008-09-14 15:22:38] George Mauer

Here's one, I like how setting default values on function parameters that aren't supplied is much easier:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }

(4) Funnily enough I saw this "hidden feature" in Google Reader last week. I don't get what's hidden about it - it's basic syntax. Try if($var = true) for example. - Ross
(8) Easier than what? Most language have this feature. - Christian Davén
(10) Easier than C# (and I think C++, and Java) - George Mauer
(8) C++ does support default parameter values. - sjobe
Real object orientated languages support overloading method names which makes this feature work the same. - whiskeysierra
(2) c# doesn't support default values at all. you have to write an overloaded function and always declare the value which is just plain cumbersome - DeveloperChris
C# will support default values in the 4.0 release. Albeit supposedly mostly for COM interop support - George Mauer
This is something I'm used to in C++ and Python. Default args are one of the things I think are omissions in some languages, not just cool features in other languages. - Ivan Vučica
Easier than JavaScript. - philfreo
29
[+21] [2009-02-16 01:19:55] Bob Fanger

Quick and dirty is the default.
The language is filled with useful shortcuts, This makes PHP the perfect candidate for (small) projects that have a short time-to-market. Not that clean PHP code is impossible, it just takes some extra effort and experience.

But I love PHP because it lets me express what I want without typing an essay.

PHP:

if (preg_match("/cat/","one cat")) {
   // do something
}

JAVA:

import java.util.regex.*;
Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat")
if (m.find()) {
  // do something
}

And yes, that includes not typing Int.


(4) you should use strpos instead: if (false !== strpos("one cat", "cat")) { - OIS
(17) @OIS the purpose of his example was to illustrate and compare the running of a quick regex match, not how to find the string "cat" in "one cat". - dcousineau
What the hell is preg()? - eyelidlessness
Good call @eyelidlessness. I used ereg() for serveral years, went the preg route since php 5.3. I don't like deprecated messages ;-) - Bob Fanger
(19) Java: if (Pattern.matches("cat", "one cat")) { // do something } Stop complaining about java if you don't know it. - whiskeysierra
(2) Btw, thats a -1 for speaking badly about Java ;P - whiskeysierra
(3) +1 Willi how do you do preg_replace('/([<[]!--\s*)(\S*?)(\s*--[>]]?)/se', "\$this->Choose('\\1','\\2','\\3',\$data)", $text); in Java? This finds a comment in the input text and then calls a function with the matched elements which in this case $this->choose(...) decides what to replace the match with and returns the results. - DeveloperChris
(1) Regex is PHP is pretty crappy... I'd much rather have Perl or JavaScript style Regex where the // is built into the language. - cdmckay
30
[+16] [2009-06-30 03:51:39] Shane H

Output buffering via ob_start() is far more useful than most realize. The first hidden feature here is that ob_start accepts a callback:

function twiterize($text) {
    // Replace @somename with the full twitter handle
    return preg_replace("(\s+)@(\w)+(\s+)", "http://www.twitter.com/${2}", $text);
}

ob_start(twiterize);

Secondly, you can nest output buffers... Using the previous example:

ob_start(parseTemplate);
 // ... 
 ob_start(twiterize);
   // ...
 ob_end_flush();
 // ... 
ob_end_flush();

Help contents, text ads, dictionary/index functionality, linkify, link-redirection for tracking purposes, templating engine, all these things are very easy by using different combinations of these 2 things.


Didn't know about the nesting. Nice. - Peter Lindqvist
(2) I know its lazy but I use output buffering so deep in my code I can add headers and totally avoid the headers already sent error. This is most noticeable in templating, if somewhere deep in a nested template an error occurs its simple to add a header to redirect the user to an error page. - DeveloperChris
To expand on the post by DeveloperChris, I find it odd that most people don't realize it's a GREAT way to convert characters on the fly without having to worry about whence they came from. I type mostly Polish pages, and they need to be in ISO-8859-2. However, most simple editors only do Windows-1250. I've seen source files with, say, translation tables coded directly in 8859-2, but it's a PAIN to maintain. Drop a nice conversion buffer on top of the thing and voilla! - a huge pain gone, and the code is suddenly more readable. - Egon_Freeman
31
[+16] [2010-06-24 14:50:03] manixrock

You can use break N; to exit nested loops (to compensate for the lack of goto). For example

for (int i=0; i<100; i++) {
    foreach ($myarr as $item) {
        if ($item['name'] == 'abort')
            break 2;
    }
}

More info here - http://php.net/manual/en/control-structures.break.php


I guess that 'feature' better remains HIDDEN or we will soon have dozens of PHP 'programmers' using GOTO's. GOTO's are evil! But anyways, didn't know about that one... Nice :) - user312650
(2) goto actually isn't lacking anymore ... - NikiC
It's very helpful and safe, as long as we're not dealing with objects/structures that need to be, for a lack of a better word, "deallocated". But all in all, I really do miss this in other languages - it's much more clear and unambiguous than any GOTO could ever be, I think. - Egon_Freeman
32
[+15] [2008-09-14 19:15:01] Jan Gorman

Actually, you're not quite right about that you cannot specify what types a method expects, it does work as you'd expect.

function foo ( array $param0, stdClass $param1 );

Note: This only works for 'array' and object names.

And so on, and you can even pass in your own classes as expected parameters. Calling the methods/functions with something else will result in a fatal error.

Another hint about a good intellisense in PHP. We use ZendStudio and it will actually work a lot better if you write good PHPDocs for your methods, it will look into those when hinting.


(2) According to ch2.php.net/language.oop5.typehinting, "string" isn't supported for type hinting. "array" is supported from PHP 5.1 on, and specific object types are supported since 5.0. - JW.
(1) To reinforce JW, scalar types are not supported when type-hinting (except for arrays), however all types are supported when type-casting. - dcousineau
(3) I was with you until you suggested ZendStudio was an even remotely passable IDE. - fiXedd
Typehinting for scalars will be available as of PHP 5.4 - NikiC
(1) Also, the note reads "This only works for 'array' and object names." but to be totally pedantic about it, it should read: "This only works for 'array' and class names." - wilmoore
33
[+13] [2008-09-16 11:31:36] Egon_Freeman

a) the manual -- extremely comprehensive, up-to-date and just a huge source for inspiration while problem-solving - stuck? browse/search the manual, it'll come to you

b) arrays - they're plastic, they're associatively indexed, they can be easily nested (!) to make up some wild data structures, and there's a multitude of functions just for array operations alone. Oh, and did I mention treating separate variables as an array of values?

c) eval() and similar constructs (like dynamic variable and function names) which allow for much greater flexibility (and are still relatively safe provided you know what you're doing) - nothing beats a program that basically defines its own process flow (or even specific execution) on the fly

d) most probably the easiest thing to overlook: as almost everything in the ZEND engine is a zVal (which in essence is a collection of pointer references), the ability to return about anything as a function return value


Also, I'd like to point out one great feature, but one which is related more to PHP source than the language (and so - listed separately):

e) the ease of writing C extensions (mostly interfaces for other objects like OpenAL or SDL) - great source code structure and about as many powerfull tools on the 'inside' as there are on the 'outside' - if you ever need to expand the functionality just that little bit further.


(4) I've been writing PHP full time for 5 years now, and haven't encountered a single situation in which I legitimately needed to use eval() or variable variables. - Frank Farmer
(1) Readability of eval()-using programs is ... ungood. Worse than "goto" imho, but just like "goto", might have legitimate uses. - Ivan Vučica
@Frank: extremely useful when coding with someone doing extreme GET operations (near the URI length limit). Declare a table and drive through it with automatic sanitization of inputs. Wasn't extremely needed, but it made my life that much easier. @Ivan: I will agree, it's horrible. On the other hand, there are cases where similar - and yet different - functions need to center around a common core. At one point it was much easier for me to just generate these at runtime, since the accepted standard was to declare PHP functions as external commands used by the interface. Lots of time saved. - Egon_Freeman
34
[+13] [2009-03-20 09:56:37] christian studer

Date functions. I have to handle a lot of time information and date strings all day long, so functions like strftime() [1] and strtotime() [2] are just awesome.

[1] http://www.php.net/strftime
[2] http://www.php.net/strtotime

(6) Make sure you check out DateTime. php.net/datetime - Annika Backstrom
(2) Actually strtotime sucks, because the magic is nowehere documented and you can't use a custom format for parsing. -1 - whiskeysierra
(1) Agreed with the above comments; strtotime() is terrible, but 5.3's DateTime is much better (as you can specify the input format exactly). - El Yobo
(3) I completely disagree. Doing dates in PHP was horrid until DateTime came around. - cdmckay
35
[+13] [2009-06-22 15:26:41] Eric Muyser

Besides instant access to start coding away at anything you need for a website?

Besides magic methods and reflections, some interesting functions are:

  1. serialize [1] / unserialize [2] - state saving goodness via sql, cookies, processes, flatfile. good stuff.
  2. json_encode [3] / json_decode [4] - instant AJAX fun
  3. get_class [5] - helpful for those weary loose-typing moments
  4. call_user_func_array [6] - powerful when you can work with your code as strings (think dynamic)
  5. method_exists [7] - reflection
  6. func_num_arg s [8] / func_get_arg [9] - unknown arguments ftw
  7. set_error_handler [10] / set_exception_handler [11] - very good debugging capabilities for a scripting language
[1] http://ca.php.net/serialize
[2] http://ca.php.net/unserialize
[3] http://ca.php.net/json_encode
[4] http://ca.php.net/json_decode
[5] http://ca.php.net/get_class
[6] http://ca.php.net/call_user_func_array
[7] http://ca.php.net/method_exists
[8] http://ca.php.net/func_num_args
[9] http://ca.php.net/func_get_args
[10] http://ca.php.net/set_error_handler
[11] http://ca.php.net/set_exception_handler

As a side-effect of that you have a heavily polluted global namespace. - cdmckay
36
[+13] [2009-07-17 18:16:06] Alex L

Ctype functions [1] are faster than preg_match() for basic character validation.

ctype_alnum() — Check for alphanumeric character(s)
ctype_alpha() — Check for alphabetic character(s)
ctype_cntrl() — Check for control character(s)
ctype_digit() — Check for numeric character(s)
...etc...

[1] http://us3.php.net/manual/en/ref.ctype.php

Very nice - I have never heard of these, and they are enabled by default without the need for installing or configuring additional PHP modules. Can anyone posit why they're not used more often? - cam8001
Forgot them..thx. - eddy147
37
[+12] [2009-06-21 22:12:05] Justin Johnson

Error suppression via the error control operator, @ [1], should almost never be used. It promotes lazy and non-defensive coding practices by simply ignoring errors, creates debugging nightmares since errors of all types--even fatal ones--will be suppressed, and, in some cases, can cause a hit to performance (especially when suppressing large quantities of errors).

[1] http://www.php.net/manual/en/language.operators.errorcontrol.php

(2) I'm glad you said 'almost never'. The function fopen() is notorious for throwing a warning and returning a testable failure value when it can't open a file. The only solution is, unfortunately, to use @fopen(). - staticsan
I try to avoid making over-zealous statements about anything relating to programming. I find that it always comes back to haunt us. But ya, parse_url is a hassle too ;) - Justin Johnson
This is a feature??? - alex
(1) Yes, it is. The "hidden" part about it is that you shouldn't generally use it ;) - Justin Johnson
Lots and lots of notices in the log for undefined indexes can be irritating. I usually @ any isset($anything['something']) to avoid so many notices. - Alex S
(2) Good defensive programming isn't just ignoring the problem. Besides, you shouldn't get any notices when using isset or empty - Justin Johnson
(2) Shadow: if you are getting lots and lots of notices its an indication of poor coding practices. Suppressing the error is a head in the sand attitude. It can come back and bite you. if a value is meant to be there and its not then its an error. if the value can be undefined then you should test for it. Security weaknesses can result otherwise. - DeveloperChris
in some special cases you actually MUST use this operator to make code compatible with other systems/versions. - Newbie
That's why I said "almost never" and not "never" - Justin Johnson
@staticsan: That's not true. Use file_exists prior to attempting to perform file operations. - Lotus Notes
The problem with that is that file_exists() followed by fopen() isn't atomic. Sometimes that's not a problem; sometimes it is. - staticsan
(1) @staticsan: Indeed, but it's not just fopen(). Most functions that deal with external data sources, esp. on network, have this flaw. Connecting outside the pref. environment is always risky, and about 99% of the time there's a way to test for failure one way or the other. And then there are the functions that NEITHER throw an error NOR return a testable failure result, but I can't name even one off the top of my hand (though I remember seeing at least one), so it's not all bad. Still, it's always better to have more warnings than less, and to use the @ like GOTO - with the respect it deserves. - Egon_Freeman
@Lotus Notes: I'd love to see You do a file_exists() on a remote HTTP server. :D I know, it's not encountered often, but there it is. Connecting and checking for it is usually a huge pain, but oftentimes the best plan. Unless of course, it's allowed to fail safely, and thus the @ is justified. - Egon_Freeman
Yes, there are several culprits. I mentioned only fopen() because far-and-away that's the one that I encounter the most often. I do the same belt-and-braces approach around mysql_connect(), too. - staticsan
38
[+12] [2009-07-25 23:06:09] Elzo Valugi

filter_var [1] function. Not a hidden pearl, but pretty new.

[1] http://es.php.net/manual/en/function.filter-var.php

39
[+10] [2009-07-01 01:43:24] djn

Well, I've recently delivered my first GUI application to a paying customer - written in PHP! It gathers data from a barcode reader or from GUI pushbuttons, checkboxes, radio buttons or text fields, stores to SQLite or remote MySQL, launches other Windows apps, sends zipped XML reports as email attachments, encrypts and decrypts stored data and even plays a sound when done.

Did it with miniPHP [1] and Winbinder [2]. Is that hidden enough? I guess not many PHP developers have really tried this out.

[1] http://www.exvision.net/miniphp.php
[2] http://winbinder.org/

I'd guess that not many PHP devs have tried it out because there's little in the way of PHP connections to OS APIs. - eyelidlessness
(2) -1, there is a reason for not trying it - whiskeysierra
(1) +1 for doing this. I use Winbinder, PHP-GTK and a load of other stuff as well. As for the connections to OS, that's why some nifty libs exist, like php-opengl or php-openal. I know that most of this SHOULD be written in C++, but it's an interesting challenge nevertheless. And most importantly, it does AWAYYYYYY with most clutter found in "proper Windows apps" - I don't need heavy functionality and all kinds of cleverness that evolved over many years and are now "standard" - it just clutters my code up to a point where I don't recognize it any more. 3k vs 300-byte source upon creation, anyone? - Egon_Freeman
40
[+8] [2009-04-27 17:24:03] Luc M

You can easily add an element to an array.

$my_array = array();
$my_array[] = 'first element';
$my_array[] = 'second element';

Element may be anything: object, array, scalar...


hidden, really? - Gabriel Sosa
He asked "...what are your favorite features of PHP?" - Luc M
The first line in unnecessary. - Ilya Birman
(9) Quite the opposite; the absence of that line is the source of many problems and bugs. - Anax
(7) "The first line in unnecessary" <- totally wrong! if you do not initialize the array, you can get quite a lot problems in different servers. You should ALWAYS initialize everything before use. - Newbie
(1) Not to mention that plainly declaring the array to be as such makes for a more readable code. - Egon_Freeman
41
[+8] [2009-11-08 19:56:35] Frank Koehl

As others have mentioned, the ability to run PHP at the command line level is fantastic. I set PHP scripts as cron jobs for data cleanup and backup purposes all the time. Just start the file with these lines:

#!/usr/bin/php5
<?php
// start coding here

Note that the first line may be different depending on where PHP is installed on your system.

From here, it's easy to implement PHP for more complex system-level processes, like daemons [1].

[1] http://www.phpclasses.org/browse/file/8958.html

(2) Alternately you can point to #!/usr/bin/env and let the system find it for you. - Gipetto
It just sucks that you can't do class autoloading in CLI otherwise it's a great feature. - Javier Parra
(3) protip: use #!/usr/bin/env php and it will be less dependent on where the php binary resides on disk. - Harold1983-
You can also use php script.php. Not as short, but more guaranteed to work on different machines. - Glacials
42
[+8] [2010-06-28 23:19:21] Xeoncross

Shorthand Boolean Chains

<?php

TRUE AND print 'Hello';
FALSE OR print 'World';

// Prints "Hello World";

// Complex example...
User::logged_in() or die('Not allowed');
User::is_admin() AND print 'Admin Area';

Which is really useful if you have PHP files in a web-accessable area. By inserting this little tidbit at the top of each file you can make sure that no-one can access any file but index.php

<?php defined('YOURCONSTANT') or die('Not allowed');

///rest of your code

(4) That would print "HelloWorld" not "Hello World". - Mark Tomlin
43
[+7] [2008-09-22 09:52:09] iAn

Built in filters for parsing variables against specific predefined types - as well as covering the basics (int/float etc), extends to covering emails, urls and even if a variable is a valid regular expression.

http://ch2.php.net/manual/en/book.filter.php


44
[+6] [2008-09-15 14:23:07] Annika Backstrom

Typecasting [1] and the ctype_* [2] functions become important to ensure clean data. I have made extensive use of exceptions [3] lately, which has greatly simplified my error handling code.

I wouldn't say the language has lots of killer features. (At least, I don't find much occasion to seek them out.) I like that the language is unobtrusive.

[1] http://us.php.net/manual/en/language.types.type-juggling.php#language.types.typecasting
[2] http://us.php.net/manual/en/book.ctype.php
[3] http://us.php.net/manual/en/language.exceptions.php

Why didn't I find out about Ctype Functions earlier? Very useful! - Alec
45
[+6] [2009-07-17 05:08:03] RaYell

Using array elements or object properties inside strings.

Instead of writing

$newVar = $ar['foo']['bar'];
echo "Array value is $newVar";

$newVar = $obj->foo->bar;
echo "Object value is $newVar";

You can write:

echo "Array value is {$ar['foo']['bar']}";
echo "Object value is {$obj->foo->bar}";

You can, but you shouldn't. Interpolated variables in strings is risky (the parsing is more complex) and harder to maintain. - staticsan
I think it's risky to write variables without braces. - RaYell
@staticsan Care to explain why it's riskier and harder to maintain? I find interpolation to be very convenient versus "foo:" . $bar style stuff. A good IDE will highlight interpolated variables as well so it's not difficult to maintain. - cdmckay
46
[+6] [2009-10-10 18:44:28] Alex L

The ReflectionClass [1] class provides information about a given class.

$classInfo = new ReflectionClass ('MyClass');
if ($classInfo->hasMethod($methodName)) 									
{
  $cm = $classInfo->getMethod($name);   								
  $methodResult = $cm->invoke(null);
}

Among other things, useful to check if a method exists and call it.

[1] http://us.php.net/manual/en/class.reflectionclass.php

47
[+5] [2009-06-21 22:20:56] Peter Goodman

preg_split(), array_intersect(), and array_intersect_key().


48
[+5] [2010-06-22 02:06:13] bob-the-destroyer

Just about any file type can be included, from .html to .jpeg. Any byte string found inside bound by PHP open tags will be executed. Yes, an image of goat.se can contain all your usual utility functions. I'm guessing the internal behavior of include is to convert the input file to string, and parse for any php code.


49
[+4] [2008-09-15 13:05:16] pilsetnieks

specifying implicitly which parameter type a method expects

Actually, this one is partly possible (at least in PHP5) - you can specify the type for array and object parameters for functions and methods, though you are out of luck in case of scalar types.

class Bar
{
    public function __construct(array $Parameters, Bar $AnotherBar){}
}

Apart from this one and the magic methods Allain mentioned, I also find the interfaces provided by SPL (Standard PHP library) indispensible - you can implement the necessary methods in your class, for example, I particulary like the ArrayAccess and Iterator interfaces, that allow using an object like an associative array or iterating over it just like any simple array.


"though you are out of luck in case of scalar types" << Yeah, totally sucks too. I work @ a mostly PHP shop, and we wanted to start writing all our PHP method/function parameters with types as a good coding practice. We ended up not doing so when we realized that we wont be able do to things like function foo(int a, int b, Bar c){} - sjobe
Your example is misleading. The code you provide is doing type-casting which supports scalar types. (int)$i will return an int (and not a string representation), as well as (Bar)$i will return a Bar or failure. Type hinting is done at the function definition level (function foo($a, array $b, Bar $c)) and only supports hinting arrays and objects. - dcousineau
50
[+4] [2009-05-10 01:44:51] Jason

I'm partial to the other PHP users out there. It's easy to get answers and direction when necessary.


51
[+4] [2009-06-22 19:57:21] Pablo Livardo

I also like the difference between ' and ".

$foo = 'Bob';
echo 'My name is {$foo}'; // Doesn't swap the variable
echo "My name is {$foo}"; // Swaps the variable

Therefore, if your string doesn't need variable swapping, don't use a ", it's a waste of time. I see lots of people declaring strings with " all the time.

Note: I use { } as it makes my variables stand out more.


(1) Also use { } for arrays: echo "Here is {$array['bob']['name']}!" - Alex L
+1 string interpolation is something many other languages lack. When moving from perl to php I breathed a sigh of relief when it worked. The only think it lacks is you can't interpolate constants. define ('FOO','bar'); echo "foo {FOO}"; doesnt work :( - DeveloperChris
String concatenation is just as fast in PHP as variable interpolation and is easier to read and maintain. - staticsan
@staticsan: I completely disagree, I find embedding variables into the string easier to read and much easier to maintain. - Josh
Great for writing out HTML without having to escape anything. - Lotus Notes
52
[+4] [2009-06-22 21:53:45] Ross

There's lots of gems hidden in the Standard PHP Library. Array access allows you to build an object that works to an array interface but add your own functionality on top.

Also when you create an ArrayAccess object by setting a flag in the constructor you can read and write an object as either an array or an object. Here's an example:

$obj = new ArrayObject(array("name"=>"bob", "email"=>"bob@example.com"),2);
$obj->fullname = "Bob Example";
echo $obj["fullname"];
$obj["fullname"]="Bobby Example";
echo $obj->fullname;

53
[+4] [2009-07-07 14:41:18] Daan

The alternative syntax for control structures [1]

There are a lot of people who don't know this syntax. When I use pure PHP for templating, this syntax offers a nice and clean way to mix simple control structures such as if or foreach with your HTML template code, usually combined with the <?= $myVar ?> short style of printing a variable.

[1] http://www.php.net/manual/en/control-structures.alternative-syntax.php

(2) Not really portable, a lot of people are moving away from it. - Peter Lindqvist
I actually disable this. it can break pages that start with <?xml ... it means you need to write out the string when thats unnecessary - DeveloperChris
wont this 'short syntax' be removed in php6? - Strae
@DaNieL Nope. They decided to keep it. - Anax
(1) @Commenters, There's a difference between the alternative syntax for control structures (which this post covers, e.g. if (2 + 2 === 4): echo 'hi'; endif;) and short tags (e.g. <?= 'hi' ?>). - strager
54
[+4] [2009-08-18 17:29:51] Saem

I suggest using PHPUnit for unit testing, if you want to have annotations for marking your tests, and data providers, and data driven tests, and so on. Not to mention, it seems to get all the integration love when it comes to things like continuous integration (cruise control, bamboo, hudson, etc...).

PHP 5.3, it's a big jump, and it's throughly worth it in terms of language features. It maybe rough around the edges, but this is a startup and they'll be fixed up releases by the time you launch.

As far as magic methods go __invoke() alone is a big deal, but it doesn't have the reciprocal method for it, even then, paired with array_map, array_reduce, and array_filter, and some wrappers you can do some amazing functional programming.

__get, __set, and __call are really handy as well, I used these and some interface/class naming convention trickery to implement traits prior to 5.3, but now you have traits, as well.

Also have a look at the addendum library, written by derik rethans of ezComponents, and XDebug fame, it allows you to do annotations for php 5+. It's not bad, and performance is a non-issue with caching.

For profiling, you can use xdebug + webcachegrind.

The best IDE is probably the free eclipse PDT, if you use type hinting on parameters, and phpdoc comments for parameters and returns it can figure things out from those and provide you code completion. That should give you decent intellisense.

BTW, it's tempting to do all sorts of crazy string concats, or variable variables, or variable method calls, or variable class creation, do this in more than one place, that's not well documented and easy to search via regex, and you're SCREWED. Forget hard to debug, but refactoring is a major pain. This is something people rarely consider php has NO automated refactoring tools, and refactoring large code bases is VERY hard to do in php.

A few things to caution you, even if you smell the slightest bit of possibility that you might have to deal with multi-byte chars, or 'exotic' character encodings, I strongly urge you to wrap up string handling. In fact, introducing a thin layer of indirection which allows you to shim between or act as seams for testing/injectability between your code and built-ins will make your life easier. Not strictly necessary, but unless you have the benefit of foresight, it's hard to tackle internationalization or such large cross-cutting projects.

autoload, learn it and love it. Run away from hard coded require/includes, or worse, their *_once variants, they tie your hands in terms of injection, instead use an autoloader, simplest thing is to jam all your includes in a array, keyed on the class name, and the value is the file path from some root, it's fast. The wicked thing about this is that it makes testing really easy, as you've implemented a class loader, and so you can do some really neat stuff with it.

PHP 5.3 has name spaces now, jump for joy and use them like a mad man. This alone provides an opportunity to create seams (rare) for testing/injections.

Opcode caches, file accesses are slow, to avoid them, use an opcode cache, it's not just the file access, it's all the parsing, really. If you don't have to parse PER request, it makes a BIG difference. Even doing this for a front controller/interceptor will give you a lot of benefits.

Think different, one of the most troubling things for PHP programmers if they come from Java/.Net is that your application server is spread across PHP/Apache, or whatever web server you're using.

Phing/Ant/PHPMaven early on it seems easy just to jam everything in, but build scripts are still useful in php and they have some great support.

I had trouble with method overloading, and still contend with it. I came up with a pattern to alleviate a certain aspect of it. I often had many things that could fulfill a certain parameter, so when you document it @param mixed(int|array|fooObject) if those were the possibilities, I created a static method called Caster::CastTo($param, $toTypeAsString) that would just run through a case matching the type and trying to convert it to a known type. The rest of the method could then assume that one type, or a failure to convert, and work with that. And since I jammed ALL conversions in one class, it stopped mapping of types from being a cross cutting concern, and since these functions can be individually tested, I could test them once, and rely on them everywhere else.


PHPUnit/PHPMaven are incompatible to 90% of common php frameworks. - whiskeysierra
55
[+3] [2009-03-20 16:36:54] Strae

Well, the community is in the first place for me. Whatever can your problem be, you'll always find someone who had it before and almost every time a solution... and sometimes I've seen a completely free share of ideas, ways to approach a single problem.

I'm trying to learn Python now (to grow up as... well.. programmer, can that be?) and the most useful thing of Python is the indentation. I love the PHP indentation, the $ mark for sign the variables, curly braces for loops and cycles, well, those smart things keep my code very easy to understand (even if the one who's wrote the code was little..messy up.. 'spaghetti-code', mh?)

Arrays, in PHP are pretty simple and powerful.

Databases: MySQL, Postrgee, sql; you can use almost every kind of databases.. easily.

Quick: logically depends by how is the code wrote, but usually PHP is pretty fast for small/medium application (as it lose wheel in bigger application).


56
[+3] [2009-07-23 18:21:11] dburke

I have started to switch over to python, and one thing I loved in python is the live interpreter. It wasn't until working on a php project later that I realized php does have this option, it's just not widely known. In a command prompt, type php -a and paste in any php code you want to test, but just remember to start it with <?php


You don't have to type "<?php", however you will have to type "echo" or "var_dump", and don't forget the ";". - laurentb
57
[+3] [2010-01-09 05:34:06] Gipetto

I think that their proper respect for the GOTO function is key.

http://us2.php.net/goto


The obligatory xkcd: xkcd.com/292 - Ikke
58
[+2] [2008-09-15 18:21:22] levhita

How extremely easy is to find PHP related things Examples, Applications, Classes, Documentation, Frameworks, etc...

All over the web, it's the easiest language to learn when going commando(by yourself), and also the one with more value for your time.

After learning PHP might put CMS with joomla, a blog with wordpress, etc....


Joomla is bloated - Click Upvote
After learning PHP hit CodeIgniter or Symfony for some improved development. They should help to make it easier to switch up to Ruby or Python in the future. If that's your goal of course. - Jon Winstanley
(2) i will add also "How extremely easy is to find PHP bad Examples", sometimes. people learn to write 'hello world' and they think they are an god programmer, and spread away suggestions that.. sometimes are not exactly good - Strae
59
[+2] [2009-06-21 20:57:56] redwall_hp

Let's see...

  1. Ternary operators. They work wonders for processing checkboxes in form results.

    $var = ($_POST['my_checkbox']=='checked') ? TRUE : FALSE;

  2. All of the wonderful string and array processing functions are worth trawling through. strtotime(), strlen(), and strpos() are a few of my favorites.

  3. The SimpleXML class and json_decode() function. Call a REST API or RSS feed with file_get_contents(), parse it effortlessly with one of those tools, and you're done.


(10) I know it was just an example, but your code could have been: $var = ($_POST['my_checkbox'] == 'checked'); - Matt Kantor
60
[+2] [2010-01-09 06:23:23] Axel Gneiting

The predefined interfaces:

http://php.net/manual/en/reserved.interfaces.php

For example implementing ArrayAccess will make your object appear as an array or Iterator will allow it to be used in a foreach statement.

Unfortunately you can't use "object arrays" with the native functions that take arrays as parameters.

I also found it useful to override the __call function which allows you to dynamically create properties and methods for an object.

In my database abstraction I use this to generate functions that are named by the database column names. For example if there is a column 'name' then you can change values in it by using updateByName("foo").


61
[+2] [2010-06-28 21:00:08] Codler

Lambda functions

Example - sort by field in multidimension-array

function sort_by_field($field, & $data) {
    $sort_func = create_function('$a,$b', 'if ($a["' . $field . '"] == $b["' . $field . '"]) {return 0;} 
            return ($a["' . $field . '"] < $b["' . $field . '"]) ? -1 : 1;');

    uasort($data, $sort_func);
}

Anonymous functions

Anonymous functions lets you define a function to a variable. http://www.php.net/manual/en/functions.anonymous.php


(5) create_function is soooo unelegant. Try the new PHP 5.3 syntax. - Savageman
(1) To be clear, the 5.3 syntax is the Anonymous functions - Codler
62
[+1] [2008-09-15 12:54:35] Fu86

GOOD:

  • The wide aceptance of PHP in WebHosting. Nearly every web-hosting service has PHP support.
  • Simple things can be solve with simple code. No classes or namespaces are strictly required.

BAD:

  • There is a ton of functions without any naming-convention. It is so hard to remember all these functions to use it effectively.
  • Bad coding habits, all over the web :(

(4) Agree on Bad #1, but surely Bad #2 is not a fault of the language, it's a fault of the programmer? It is possible to write beautiful PHP... honest! - HoboBen
Sure, it is posible to write beautiful code with PHP, but a awful lot of code on the web is just crap and thats a shame :( - Fu86
(3) There is plenty of awful code out there in every commonly used language. - postfuturist
(4) I think what annoys me more than the inconsistent naming is the inconsistent ordering of arguments. For example string search functions - does haystack or needle come first? In some functions the order changed a long while back - also some functions accept them in either order for compatibility. - thomasrutter
Not sure how these are hidden features of PHP... - Sasha Chedygov
@HoboBen: "It is possible to write beautiful PHP" please show me! - whiskeysierra
You missed a good point: The best documentation of any language ever. - Mark Tomlin
63
[+1] [2009-06-22 01:07:27] no_ripcord

This is great:

//file page_specific_funcs.inc

function doOtherThing(){

}

class MyClass{

}

//end file

//file.php

function doSomething(){
  include("page_specific_funcs.inc");

  $var = new MyClass(); 

}
//end of file.php

"page_specific_funcs.inc" file is only included if doSomething gets called. The declaration of classes, funcs, etc., inside methods works perfectly.


thats a -1 for PHP because lazy-loading should be handled by the container/environment. - whiskeysierra
(3) I hate code like that. It's a nightmare to change or extend as it's completely impossible to figure out dependencies. (At least for large projects). - Kimble
64
[+1] [2009-06-22 14:39:59] Israel Viana

Definitely the magic and overloading methods. Allain cited __get(), __set(), __call() and __toString(), but I also love __wakeup() and __sleep().

This magic methods are called when the object is serialized (sleep) and deserialized (wakeup). This feature ables making things like serializable Database-wrappers, which i am using in an application:

Class Connection {
   private $dsn;
   private $connection;
   ...
   public __wakeup() {
      $this->connection = ADONewConnection();
   }
}

In this way i can "save" connections in $_SESSION, etc.


65
[+1] [2009-06-22 14:54:24] David

The json_encode/decode functions in php are pretty useful, though not very hidden.


66
[+1] [2009-08-28 20:17:25] RedAssBaboon

In PHP5.3 you can place PHAR archives inside PHAR archives! Like WAR/EJB in the java world.


67
[+1] [2009-09-12 23:32:42] Kzqai

My revelations over the years have been more conceptual than language based.

1: Rendering instead of echoing.

function render_title($title){
     return "<title>$title</title";
}

so much easier to use the parts repeatably and pass them to templates when you are rendering your output instead of using echos (in which case you'd have to rely on output buffering).

2: functional programming, or at least as close as I can move towards it, functions without side-effects. Rendering, not using globals, keeping your functions to having a local scope, things like that. I thought that object oriented programming was the way to go with php for a while there, but the reduction in overhead and syntax complexity that I experienced from dropping down from object oriented methods to functional programming methods in php makes functional programing the clear choice for me.

3: Templating systems (e.g. smarty). It's taken me a long time to realize that you -need- a templating system inside what is already a template scripting language, but the seperation of logic from display that it gives you is so, so necessary.


68
[+1] [2010-01-07 17:42:32] ivanjovanovic

Lot already said about this.

Just to add that one thing that looked pretty forgotten, if not hidden, is http://talks.php.net part of the http://www.php.net. It collects lot of useful presentations, some really old, but some new and extremely valuable.


69
[+1] [2010-01-29 11:02:34] Talvi Watia

Stackable unit files

<?
// file unit1.php
$this_code='does something.';
?>

<?
// file unit2.php
$this_code='does something else. it could be a PHP class object!';
?>

<?
// file unit3.php
$this_code='does something else. it could be your master include file';
require_once('unit2.php');
include('unit1.php');
?>

<?
// file main.php
include('unit1.php');
require_once('unit2.php');
require_once('unit3.php');
?>

I purposely used include and require_once interchangeably to show what can be done, because they work differently.

There are multiple ways to construct your code or add files into your code. It is even possible to link HTML, AJAX, CSS, JAVASCRIPT, IMAGES and all sorts of files into your code dynamically.

I especially like it, because there are also no requirements of placing the includes/requires at the beginning, middle or end. This allows for more freedom, depending on the use.


70
[0] [2010-01-22 09:32:32] RJD22

Another nice feature is copy() [1]. This function makes it possible to get a file from any place(even urls work) and copy it to a local resource. So grabbing files becomes really easy.

[1] http://php.net/manual/en/function.copy.php

71
[0] [2010-01-25 19:01:10] Alexandru Mos

Magic method __callStatic.

Really useful to make singletons, like this PDO singleton class [1]

[1] http://www.php.net/manual/en/book.pdo.php#93178

Works starting with PHP 5.3 - laurentb
Yup. Sorry, I forgot to mention. - Alexandru Mos
72
[0] [2010-01-25 23:05:00] Peter

Question about the original post: Why do you need a switch statement in order to overload a method in PHP? Maybe you mean something by the term "overload" that doesn't match what I learned from C++.

As for favorite features of PHP, I like the Exception object. I find that having a standard error container makes it much easier to decouple the presentation logic from the business logic, and the throw/catch syntax makes it much easier to write automated tests for each class in isolation.


Too bad most PHP functions are not using exceptions! - laurentb
73
[0] [2010-02-23 20:39:30] GreenMatt

Using cURL [1] to set up a test suite to drive a large, complex web form and its back end application. The tests were exhaustive - at least in terms of executing every combination of acceptable inputs.

[1] http://us.php.net/manual/en/book.curl.php

74
[-1] [2009-06-27 15:55:38] nightingale2k1

the hidden features that I love from php: 1. easy to learn (also easy to missused it .. ie: bad programming habits. like you can type $something = "1" ; and then you did $something += 3 ; and suddenly $something becomes an integer .. without error message/freaking exceptions, like those in java)

  1. lots of library. go to phpclasses.org and I almost got everything from there.
  2. lots of web using it. Love it or hate it .. that's the fact ! :)
  3. simple, small and easy to maintenance. you just install xampplite + vim (my favourite) on your portable devices.
  4. cheap !!! as cheap as a beer ... for example: hosting. compared to java or .net host, php host really cheap and you can get free one from some websites (although they will put some banners / hidden thing inside your website)
  5. the documentation for php was very good !! that's the main reason i am stick to php for about 6 years (although I did some projects using Groovy/Grails)

75
[-2] [2010-06-28 20:32:44] fixo2020

You can set a check on every option when use switch statement, this is an example:

$check = "HELLO";

switch ($check) {
       case (eregi('HI', $check)):
             echo "Write HI!";
       case (eregi('HELLO', $check)):
             echo "Write HELLO!";
       case (eregi('OTHER', $check)):
             echo "Write OTHER!";
}

Bye...


(3) You know that ereg* is deprecated, right? - Maerlyn
76
[-4] [2009-06-22 05:51:07] Mark

Boolean casting, which is particularly helpful for redwall_hp's first example, above.

Instead of:

$var = ($_POST['my_checkbox']=='checked') ? TRUE : FALSE;

You can type:

$var = !!($_POST['my_checkbox']=='checked');

(8) Why doesn't $var = ($_POST['my_checkbox'] == 'checked') work? - DisgruntledGoat
I think the point that submitter wanted to make was something like: $var = !!($othervar - 1); -- testing if $othervar is 1, and setting bool. There are other legitimate uses where you want to force storing a boolean and where this is the easiest way to get one. - Ivan Vučica
(1) you realize that using !! is the same as not using the ! operator at all, right? It's like saying "not not true", instead of just saying "true" - Harold1983-
77
[-5] [2009-06-22 14:34:54] aviv

As far as i know, you can Implicit parameter type in function call:

function getInt(int $v)
{
     echo $v;
}

getInt(5); // will work
getInt('hello'); // will fail

(3) You should check the manual before you post: "Type Hints can only be of the object and array (since PHP 5.1) type. Traditional type hinting with int and string isn't supported." (php.net/manual/en/language.oop5.typehinting.php) - cdmckay
78