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?
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/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, 2], [3, 4]]
, compare this to the PHP version: array(array(1, 2), array(3, 4))
. - Rene Saarsoo
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.htmlarray(
lines? - rtpHarry
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]).
__call()
is great in frameworks with map domain.com/controller/method/ - alex
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.";
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
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("...");
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
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
or
because I don't trust everyone I work with will always be cognizant of the difference between or
and ||
- Frank Farmer
then
- JeroenEijkhof
$_GET['page']
can never be an int, unless you modify $_GET
in your PHP code. - Ionuț G. Stan
is_numeric
since that checks if it's a numeric string. - DisgruntledGoat
$page = getPage($_POST["page"]) or GTFO();
- L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
...&page=<something_not_valid>
, rather than silently swallowing it. - Halil Özgür
mysql_connect(*) or die()
- Tim
__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.phpVariable 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
${$a}
. Just so the rest of us knows that something is going on, and the two $$
are not just collapsed into one. - Thomas Ahle
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.
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);
?>
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.
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] https://www.php.net/strtrOne 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.
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
$as_string
, this is nearly the same as my little renderView function! - Halil Özgür
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.phpRead Loop
. - Buddy
PHP enabled webspace is usually less expensive than something with (asp).net. You might call that a feature ;-)
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!
wget http://example.com...
- DisgruntledGoat
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.
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.
<?=$flag?'blah':''?>
. Actually without shorttags it's still shorter. - DisgruntledGoat
if...
version doesn't make me think. - Halil Özgür
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 :)
$item->DataContent->body->{'body.content'}
. - Jesse Kochis
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"
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;
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:
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:
That url is an alias for https://www.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.
range()
can be useful for foreach( range(1, 10) as $i) { };
- alex
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
/*
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.
// ...
line comments and /* ... */
block comments. - Jordan Ryan Moore
/** /
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
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)
${''} = 456;
hahaha.... quite the abuse. - Skurmedel
${''} = 456;
. Finally a completely anonymous variable. - Halil Özgür
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.
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:
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
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 );
$defaults
should be $control_defaults
- xkeshav
... + array( ...
isn't enough to point this out? :-) - staticsan
size
would still be 30. - BDuelz
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
Here's one, I like how setting default values on function parameters that aren't supplied is much easier:
function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }
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.
//
is built into the language. - cdmckay
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.
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.
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
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.
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/strftimeBesides instant access to start coding away at anything you need for a website?
Besides magic methods and reflections, some interesting functions are:
serialize
[1] /
unserialize
[2] - state saving goodness via sql, cookies, processes, flatfile. good stuff.
json_encode
[3] /
json_decode
[4] - instant AJAX fun
get_class
[5] - helpful for those weary loose-typing moments
call_user_func_array
[6] - powerful when you can work with your code as strings (think dynamic)
method_exists
[7] - reflection
func_num_arg
s
[8] /
func_get_arg
[9] - unknown arguments ftw
set_error_handler
[10] /
set_exception_handler
[11] - very good debugging capabilities for a scripting languageCtype functions [1] are faster than preg_match() for basic character validation.
[1] https://www.php.net/manual/en/ref.ctype.phpctype_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...
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.phpisset
or empty
- Justin Johnson
file_exists
prior to attempting to perform file operations. - Lotus Notes
file_exists()
followed by fopen()
isn't atomic. Sometimes that's not a problem; sometimes it is. - staticsan
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
filter_var [1] function. Not a hidden pearl, but pretty new.
[1] http://es.php.net/manual/en/function.filter-var.phpWell, 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.phpYou 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...
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.htmlphp script.php
. Not as short, but more guaranteed to work on different machines. - Benjamin Carlsson
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
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
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.typecastingUsing 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}";
"foo:" . $bar
style stuff. A good IDE will highlight interpolated variables as well so it's not difficult to maintain. - cdmckay
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.phppreg_split(), array_intersect(), and array_intersect_key().
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.
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.
(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
I'm partial to the other PHP users out there. It's easy to get answers and direction when necessary.
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.
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;
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.
if (2 + 2 === 4): echo 'hi'; endif;
) and short tags (e.g. <?= 'hi' ?>
). - strager
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.
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).
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
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....
Let's see...
Ternary operators. They work wonders for processing checkboxes in form results.
$var = ($_POST['my_checkbox']=='checked') ? TRUE : FALSE;
All of the wonderful string and array processing functions are worth trawling through. strtotime(), strlen(), and strpos() are a few of my favorites.
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.
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")
.
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
create_function
is soooo unelegant. Try the new PHP 5.3 syntax. - Savageman
GOOD:
BAD:
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.
The json_encode/decode functions in php are pretty useful, though not very hidden.
In PHP5.3 you can place PHAR archives inside PHAR archives! Like WAR/EJB in the java world.
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.
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.
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.
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.
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.phpMagic method __callStatic.
Really useful to make singletons, like this PDO singleton class [1]
[1] http://www.php.net/manual/en/book.pdo.php#93178Question 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.
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.phpthe 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)
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...
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');
$var = ($_POST['my_checkbox'] == 'checked')
work? - DisgruntledGoat
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