Php hints

The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.

This document was shared by chx in #drupal.hu irc channel. Original was found on github, but unfortunally it's deleted, so I don't know who write it.

I've just saved it for me unpublished, but now, I'm publishing and add some style.
--------------------------------------------------------------------------

This document discusses difficult traps and pitfalls in PHP, and how to avoid, work around, or at least understand them.

If you're brand new to PHP, read [[Articles/PHP Intro]] first.

All of it! PHP is a Terrible Language! LOL!

PHP has more (and more severe) design flaws than most modern languages. Despite this, Facebook has built a 50-billion-dollar enterprise on it.

If this is going to be a problem, you should take some time and really reflect on your career choices.

usort(), uksort(), and uasort() are Slow

This family of functions is extremely slow. You should avoid them if at all possible. Instead, build an array which contains surrogate keys that are naturally sortable with a function that uses native comparison (e.g., sort(), asort(), ksort(), or natcasesort()). Sort this array instead, and use it to reorder the original array.

In our environment, you can often do this easily with array_psort(). You also need to account for i18n and locale-aware collation, which array_psort() will handle for you.

array_intersect() and array_diff() are Also Slow

These functions are much slower for even moderately large inputs than array_intersect_key() and array_diff_key(), because they can not make the assumption that their inputs are unique scalars as the key varieties can. Strongly prefer the key varieties.

array_uintersect() and array_udiff() are Definitely Slow Too

These functions have the problems of both the usort() family and the array_diff() family. Don't use them.

array_merge() in a Loop is Incredibly Slow

If you merge arrays like this:
[geshifilter-php] $result = array(); foreach ($list_of_lists as $one_list) { $result = array_merge($result, $one_list); } [/geshifilter-php]

...your program takes O(N^2) runtime because it generates N intermediate arrays. You should use array_merge_fast(). But be CAREFUL, don't use array_merge_fast() in a loop either! This is equally wrong:

[geshifilter-php] $result = array(); foreach ($list_of_lists as $one_list) { $result = array_merge_fast(array($result, $one_list)); } [/geshifilter-php]
Instead you should do:
[geshifilter-php] $result = array_merge_fast($list_of_lists); // Note that this is not within a loop! [/geshifilter-php]

isset(), empty() and Truthiness

A value is "truthy" if it evaluates to true in an if clause:

[geshifilter-php] $value = something(); if ($value) { // Value is truthy. } [/geshifilter-php]

If a value is not truthy, it is "falsey". These values are falsey in PHP:

[geshifilter-php] null // null 0 // integer 0.0 // float "0" // string "" // empty string false // boolean array() // empty array [/geshifilter-php]

Disregarding some bizarre edge cases, all other values are truthy. Note that because "0" is falsey, this sort of thing (intended to prevent users from making empty comments) is wrong in PHP:

[geshifilter-php] if ($comment_text) { make_comment($comment_text); } [/geshifilter-php]

This is wrong because it prevents users from making the comment "0". THIS COMMENT IS TOTALLY AWESOME AND I MAKE IT ALL THE TIME SO YOU HAD BETTER NOT BREAK IT!!! A better test is probably strlen().

In addition to truth tests with if, PHP has two special truthiness operators which look like functions but aren't: empty() and isset(). These operators help deal with undeclared variables.

In PHP, there are two major cases where you get undeclared variables -- either you directly use a variable without declaring it:
[geshifilter-php] function f() { if ($not_declared) { // ... } } [/geshifilter-php]

...or you index into an array with an index which may not exist:

[geshifilter-php] function f(array $mystery) { if ($mystery['stuff']) { // ... } } [/geshifilter-php]

When you do this, PHP issues a warning. Avoid these warnings by using empty() and isset() to do tests that are safe to apply to undeclared variables.

empty() evaluates truthiness exactly opposite of if(). isset() returns true for everything except null. This is the truth table:

VALUE if() empty() isset()

null false true false

0 false true true

0.0 false true true

"0" false true true

"" false true true

false false true true

array() false true true

EVERYTHING ELSE true false true

The value of these operators is that they accept undeclared variables and do not issue a warning. Specifically, if you try to do this you get a warning:

[geshifilter-php] if ($not_previously_declared) // PHP Notice: Undefined variable! [/geshifilter-php]

But these are fine:

[geshifilter-php] if (empty($not_previously_declared)) // No notice, returns true. if (isset($not_previously_declared)) // No notice, returns false. [/geshifilter-php]

So, isset() really means is_declared_and_is_set_to_something_other_than_null(). empty() really means is_falsey_or_is_not_declared(). Thus:

  • If a variable is known to exist, test falsiness with if (!$v), not empty(). In particular, test for empty arrays with if (!$array). There is no reason to ever use empty() on a declared variable.
  • When you use isset() on an array key, like isset($array['key']), it will evaluate to "false" if the key exists but has the value null! Test for index existence with array_key_exists().

Put another way, use isset() if you want to type "if ($value !== null)" but are testing something that may not be declared. Use empty() if you want to type "if (!$value)" but you are testing something that may not be declared.

foreach() Does Not Create Scope

Variables survive outside of the scope of foreach(). More problematically, references survive outside of the scope of foreach(). This code mutates $array because the reference leaks from the first loop to the second:

[geshifilter-php] $array = range(1, 3); echo implode(',', $array); // Outputs '1,2,3' foreach ($array as &$value) {} echo implode(',', $array); // Outputs '1,2,3' foreach ($array as $value) {} echo implode(',', $array); // Outputs '1,2,2' [/geshifilter-php]

Avoid using foreach-by-reference. If you do opt to use it, unset the reference after the loop:

[geshifilter-php] foreach ($array as &$value) { // ... } unset($value); [/geshifilter-php]

unserialize() is Incredibly Slow on Large Datasets

The performance of unserialize() is nonlinear in the number of zvals you unserialize, roughly O(N^2).

zvalsapproximate time
100005ms
10000085ms
10000008,000ms
1000000072 billion years

var_export() Loves to Kill Babies

If you try to var_export() an object that contains recursive references, your program will terminate. You have no chance to stop this from happening. Avoid var_export() unless you are certain you have only simple data. You can use print_r() or var_dump() to display complex variables.

json_encode() Gives Up Very Easily

PHP's json_encode() completely discards data if it has an invalid UTF-8 subsequence. Use fb_json_encode() (and fb_json_decode()) to avoid these problems.

call_user_func() Breaks References

If you use call_use_func() to invoke a function which takes parameters by reference, the variables you pass in will have their references broken and will emerge unmodified. That is, if you have a function that takes references:

[geshifilter-php] function add_one(&$v) { $v++; } [/geshifilter-php]

...and you call it with call_user_func():

[geshifilter-php] $x = 41; call_user_func('add_one', $x); [/geshifilter-php]

...$x will not be modified. The solution is to use call_user_func_array() and wrap the reference in an array:

[geshifilter-php] $x = 41; call_user_func_array( 'add_one', array(&$x)); // Note '&$x'! [/geshifilter-php]

This will work as expected.

You Can't Throw From __toString()

If you throw from __toString(), your program will terminate uselessly and you won't get the exception.

An Object Can Have Any Scalar as a Property

Object properties are not limited to legal variable names:

[geshifilter-php] $property = '!@#$%^&*()'; $obj->$property = 'zebra'; echo $obj->$property; // Outputs 'zebra'. [/geshifilter-php]

So, don't make assumptions about property names.

There is an (object) Cast

You can cast a dictionary into an object.

[geshifilter-php] $obj = (object)array('flavor' => 'coconut'); echo $obj->flavor; // Outputs 'coconut'. echo get_class($obj); // Outputs 'stdClass'. [/geshifilter-php]

This is occasionally useful, mostly to force an object to become a Javascript dictionary (vs a list) when passed to fb_json_encode().

$arr['42'] refers to the same value as $arr[42]

So:

[geshifilter-php] $arr = array(); $arr[42] = 'spoo'; echo $arr['42']; // outputs "spoo" echo $arr[' 42']; // note leading space; "undefined index"[/geshifilter-php]

Do you really, really want to put an integer-like string key in an array? All is not lost! You can do it with an array cast, but good luck getting that value back.

[geshifilter-php] $obj = new stdClass(); $zero = 0; $obj->$zero = 'blub'; $arr = (array)$obj; var_export($arr); // outputs "array( '0' => 'blub' )". BUT: echo $arr['0']; // undefined index, fool! [/geshifilter-php]

There is a Builtin __PHP_Incomplete_Class Which Answers to No Master

See _warn_incomplete_object().

PHP Leaks Like a Sieve

Everything in PHP leaks a lot of memory. "Everything" does NOT mean "some rare library functions which you can avoid if you are careful", it means "basic array operations" and probably "comments". Do not build long-running PHP services.

Invoking "new" With an Argument Vector is Really Hard

If you have some $className and some $argv of constructor arguments and you want to do this:

[geshifilter-php] new $className($argv[0], $argv[1], ...); [/geshifilter-php]

...you'll probably invent a very interesting, very novel solution that is very wrong. Use newv().

Equality is not Transitive

This isn't terribly surprising since equality isn't transitive in a lot of languages, but the == operator is not transitive:

[geshifilter-php] $a = ''; $b = 0; $c = '0a'; $a == $b; // true $b == $c; // true $c == $a; // false! [/geshifilter-php]

When either operand is an integer, the other operand is cast to an integer before comparison. Avoid this and similar pitfalls by using the === operator, which is transitive.

All 676 Letters in the Alphabet

This doesn't do what you'd expect it to do in C:

[geshifilter-php] for ($c = 'a'; $c <= 'z'; $c++) { // ... } [/geshifilter-php]

This is because the successor to 'z' is 'aa', which is "less than" 'z'. The loop will run for ~700 iterations until it reaches 'zz' and terminates. That is, $c will take on these values:

[geshifilter-php] a b ... y z aa // loop continues because 'aa' <= 'z' ab ... mf mg ... zw zx zy zz // loop now terminates because 'zz' > 'z' [/geshifilter-php]

Instead, use this loop:

[geshifilter-php] foreach (range('a', 'z') as $c) { // ... }[/geshifilter-php]

Ternary operator is left-associative

Unlike in C or Java, the ternary operator associates from left to right, not from right to left. So for example, the following code will not do what you want:

[geshifilter-php] $num = 0; $text = ($num === 0) ? 'zero' : ($num === 1) ? 'one' : 'many'; // $text is now 'one' because the above call is equivalent to this: // $text = (($num === 0) ? 'zero' : ($num === 1)) ? 'one' : 'many'; [/geshifilter-php]

Comments

closely background

closely background [url=http://www.cialisles.com/#]cialis without a prescription[/url] unfortunately profession perfectly signature
ed meds online without doctor prescription obviously name
cialis without a prescription where mood http://cialisles.com

Турецкие сериалы серия

Турецкие сериалы серия русская озвучка Прямой Эфир

Русские сериалы сезон серия

Русские сериалы сезон серия Новые видео смотреть в HD Сериалы

Русские сериалы смотеть новые

Русские сериалы смотеть новые серии Смотреть фильмы онлайн

Новые сериалы сезон серия

Новые сериалы сезон серия Фильмы онлайн, смотреть бесплатно Кино онлайн

Турецкие сериалы серия

Турецкие сериалы серия русская озвучка Live

Русские сериалы смотреть

Русские сериалы смотреть онлайн все серии подряд Фильмы

Русские сериалы смотеть новые

Русские сериалы смотеть новые серии Смотреть Фильмы в HD онлайн. Список фильмов

Поледние сериалы серия

Поледние сериалы серия русская озвучка Фильмы

Русские сериалы серия русская

Русские сериалы серия русская озвучка Фильмы онлайн, смотреть бесплатно Кино онлайн

Русские сериалы серия русская

Русские сериалы серия русская озвучка Онлайн кинотеатр

Поледние сериалы сезон серия

Поледние сериалы сезон серия Бесплатные фильмы и сериалы смотреть онлайн

Поледние сериалы смотреть

Поледние сериалы смотреть онлайн все серии подряд Фильмы онлайн, смотреть бесплатно Кино онлайн

Поледние сериалы все серии

Поледние сериалы все серии Фильмы - смотреть онлайн бесплатно в хорошем качестве

Новые сериалы все серии

Новые сериалы все серии Фильмы онлайн, смотреть бесплатно Кино онлайн

Русские сериалы смотреть

Русские сериалы смотреть онлайн все серии подряд Новые видео смотреть в HD Сериалы

Поледние сериалы смотреть

Поледние сериалы смотреть онлайн все серии подряд Фильмы

Поледние сериалы серия в HD.

Поледние сериалы серия в HD. Новинки кино смотреть онлайн

Русские сериалы серия в HD.

Русские сериалы серия в HD. Смотреть видео онлайн в хорошем качестве

Русские сериалы все серии

Русские сериалы все серии Онлайн кинотеатр

fully agent careprost 3ml eye

fully agent careprost 3ml eye drops however junior too ball bimatoprost each beginning
personally group careprost buy online fast tennis [url=https://bimatoprostonline.confrancisyalgomas.com/#]bimatoprost cost[/url] abroad nothing buy naltrexone initially chain https://careprost.confrancisyalgomas.com/

Новые сериалы сериал новая

Новые сериалы сериал новая серия Новые видео смотреть в HD Сериалы

Русские сериалы все серии

Русские сериалы все серии Онлайн кинотеатр

Турецкие сериалы смотреть

Новые сериалы серия русская

Новые сериалы серия русская озвучка Новые видео смотреть в HD Сериалы

Поледние сериалы все серии

Поледние сериалы все серии Фильмы

Турецкие сериалы серия в HD.

Турецкие сериалы серия в HD. Бесплатные фильмы и сериалы смотреть онлайн

Турецкие сериалы серия в HD.

Турецкие сериалы серия в HD. Смотреть фильмы онлайн

Русские сериалы сериал серия

Русские сериалы сериал серия Прямой Эфир

Поледние сериалы сериал новая

Поледние сериалы сериал новая серия Фильмы онлайн, смотреть бесплатно Кино онлайн

Поледние сериалы серия

Поледние сериалы серия русская озвучка Бесплатные фильмы и сериалы смотреть онлайн

I really like it when folks

I really like it when folks get together and share views.
Great site, stick with it!

Турецкие сериалы сериал новая

Турецкие сериалы сериал новая серия Фильмы онлайн, смотреть бесплатно Кино онлайн

Поледние сериалы сезон новая

Поледние сериалы сезон новая серия Новые видео смотреть в HD Сериалы

lifta tadalafil erfahrungen

lifta tadalafil erfahrungen [url=http://cialisle.com/]cialis
online[/url] tadalafil beneficios cialis online tadalafil flushing riesgos del tadalafil
http://www.cialisle.com/ tadalafil cuanto dura efecto http://www.cialisle.com/

Стройненькая блонда в


Стройненькая блонда в чулочках мама дрочит сыну эротические рассказы
любит позировать у себя на кровати. Телочка с великолепным телом меряет на себя высокие каблуки и усаживается в постельке. Она выставляет на всеобщее обозрение для начала аппетитненький анус. За тем подруга касается через лифон аленького цвета к дойкам и возбужденно трет их. Соблазнительная нимфа готова к необыкновенному траху тетя с мамой дрочат сыну
в самых удивительных позициях.

Hi there i am kavin, its my

Hi there i am kavin, its my first occasion to commenting anywhere, when i read this paragraph i thought i could also make comment due to
this good post.

Woah! I'm really enjoying the

Woah! I'm really enjoying the template/theme of this site.
It's simple, yet effective. A lot of times it's tough to
get that "perfect balance" between superb usability
and visual appeal. I must say you've done a superb job with this.
In addition, the blog loads very fast for me on Safari.
Superb Blog!

I visit daily some blogs and

I visit daily some blogs and sites to read content, but this website offers quality based posts.

Не молодая уже русская


Не молодая уже русская мамочка в сногсшибательных чулках мама и сын порно фото на телефон
явилась с работы неимоверно заведенной. Ее шеф ущипнул ее за задницу и у этой спелой российской мадемуазели заалеяли давние, очень давно позабытые желания. Чтобы угомонить свербеж в собственной мохнатой мокрощелке, зрелая, похотливая мамаша пожелала развратить собственного сынишку на инцест мама учит сына оргазму
. Сбросив с мужичка брюченки, мамаша забацала классный минет ему прямо в предбаннике, а после растопырила собственные ноги в чулочках, запустив завёдшийся хуй сына в собственную мокренькую, обросшую писю...

Просматривайте самое интересное порево кровосмешание тут - порно мамки устроили групповуху с сыновьями

herbalogix kratom kratom

herbalogix kratom kratom colors bitcoin buy
orders [url=http://kratomsaleusa.com/#]is kratom illegal[/url]
red kali kava kratom http://kratomsaleusa.com/

immediately sport

immediately sport [url=http://cialissom.com/#]cialis usa[/url]
clearly gift cialis usa tourist collection each particular http://cialissom.com/ suddenly chain http://cialissom.com/

This is very interesting, You

This is very interesting, You are a very skilled blogger.
I have joined your rss feed and look forward to seeking
more of your fantastic post. Also, I have shared your site in my social networks!

I was wondering if you ever

I was wondering if you ever thought of changing the
layout of your site? Its very well written; I love what youve
got to say. But maybe you could a little more in the way of content
so people could connect with it better. Youve got an awful lot of text
for only having one or 2 pictures. Maybe you could space it out
better?

Hello! Quick question that's

Hello! Quick question that's totally off topic. Do you know how
to make your site mobile friendly? My site looks weird when browsing from my apple iphone.
I'm trying to find a template or plugin that might be able to correct
this problem. If you have any suggestions, please share.
With thanks!

Post Utme Past Question

I must say that your write up

I must say that your write up is very clean and understandable even for a child to understand...keep writing.

May I just say what a relief

May I just say what a relief to discover an individual who really knows what they're discussing online.
You certainly understand how to bring an issue to light and make it important.
More and more people should check this out and understand this side of the story.
I was surprised you aren't more popular given that you definitely possess the gift.Hilton

Nice post. I was checking

Nice post. I was checking continuously this blog and I am impressed!
Very useful information specially the last part :) I care for such info much.
I was seeking this certain info for a very long
time. Thank you and good luck.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Internal paths in double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or relative path.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <del> <img>
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • Allowed HTML tags: <a> <blockquote> <br> <cite> <code> <dd> <del> <div> <dl> <dt> <em> <li> <ol> <p> <span> <strong> <ul>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <bash>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <mysql>, <php>, <python>, <ruby>, <sql>. The supported tag styles are: <foo>, [foo].
  • Each email address will be obfuscated in a human readable fashion or (if JavaScript is enabled) replaced with a spamproof clickable link.