PHP 5.4 vs 5.3 Difference = What To Watch Out For When Coding With New Version of PHP

Written by Gregory Milby | Tuesday, August 7th, 2012
, , , ,

Each major release of any framework can make someone begin to second guess what is still ‘current’. Hopefully this list of incompatible changes will help server as a reference so that you do not have a site fail due to deprecated code!

Backward Incompatible Changes in PHP 5.4:

(excerpt from the php.net site:)

Although most existing PHP 5 code should work without changes, please take note of some backward incompatible changes:

  • Safe mode is no longer supported. Any applications that rely on safe mode may need adjustment, in terms of security.
  • Magic quotes has been removed, an overdue change imo.  Applications relying on this feature may need to be updated, to avoid security issues. get_magic_quotes_gpc() and get_magic_quotes_runtime() now always return FALSE. set_magic_quotes_runtime() raises an E_CORE_ERROR level error.
  • The register_globals and register_long_arrays php.ini directives have been removed.
  • Call-time pass by reference has been removed.
  • The break and continue statements no longer accept variable arguments (e.g., break 1 + foo() * $bar;). Static arguments still work, such as break 2;. As a side effect of this change break 0; and continue 0; are no longer allowed.
  • In the date and time extension, the timezone can no longer be set using the TZ environment variable. Instead you have to specify a timezone using the date.timezone php.ini option or date_default_timezone_set() function. PHP will no longer attempt to guess the timezone, and will instead fall back to “UTC” and issue a E_WARNING.
  • Non-numeric string offsets – e.g. $a['foo'] where $a is a string – now return false on isset() and true on empty(), and produce a E_WARNING if you try to use them. Offsets of types double, bool and null produce a E_NOTICE. Numeric strings (e.g. $a['2']) still work as before. Note that offsets like ’12.3′ and ’5 foobar’ are considered non-numeric and produce a E_WARNING, but are converted to 12 and 5 respectively, for backward compatibility reasons. Note: Following code returns different result. $str=’abc’;var_dump(isset($str['x'])); // false for PHP 5.4 or later, but true for 5.3 or less.  This one still has my head reeling… i’ve always used isset()/empty() as boolean – assuming the false is now returned and the true is assumed(?)… if you know ‘for sure’ – please post below.
  • Converting an array to a string will now generate an E_NOTICE level error, but the result of the cast will still be the string “Array”.
  • Turning NULL, FALSE, or an empty string into an object by adding a property will now emit an E_WARNING level error, instead of E_STRICT.
  • Parameter names that shadow super globals now cause a fatal error. This prohibits code like function foo($_GET, $_POST) {}.Honestly, in a way this could be saving us from ourselves… if you need to reference a super-global – it’s safer in the long run to filter/sanitize it before using it… no direct reference will probably save a lot of horror stories.
  • The Salsa10 and Salsa20 hash algorithms have been removed. As if I knew they were ever there? o.O
  • array_combine() now returns array() instead of FALSE when two empty arrays are provided as parameters.
  • If you use htmlentities() with asian character sets, it works like htmlspecialchars() – this has always been the case in previous versions of PHP, but now an E_STRICT level error is emitted.
  • The following keywords are now reserved, and may not be used as names by functions, classes, etc.traitcallableinsteadofThe following functions have been removed from PHP:define_syslog_variables()import_request_variables()session_is_registered(), session_register() and session_unregister().The aliases mysqli_bind_param(), mysqli_bind_result(), mysqli_client_encoding(), mysqli_fetch(), mysqli_param_count(), mysqli_get_metadata(), mysqli_send_long_data(), mysqli::client_encoding() and mysqli_stmt::stmt(). If you were using any of these as keywords as var, function or class names, go stand in the corner for 30 minutes.
In case you were using the super global variables as viable variables, don’t be hard on yourself – we’ve all done it.  However, take advantage of the filter functions – it’s painless:

FILTER_SANITIZE_EMAIL   “email” = Remove all characters except letters, digits and !#$%&’*+-/=?^_`{|}~@.[].
FILTER_SANITIZE_MAGIC_QUOTES    “magic_quotes” = Apply addslashes().
FILTER_SANITIZE_NUMBER_INT    “number_int” = Remove all characters except digits, plus and minus sign.
FILTER_SANITIZE_SPECIAL_CHARS    “special_chars” = HTML-escape ‘”<>& and characters with ASCII value less than 32, optionally strip or encode other special characters.

using them is just as painless too:


instead of: $_POST['email']
filter_var($_POST['email'], FILTER_SANITIZE_EMAIL)

Just remember that failing the filter_var test is true/false… so plan accordingly.

3 Comments

Apache Benchmark Load Testing Tool – Free And Accurate

Apache has a great load testing tool that appears to rival the best out there.  It can test against concurrent connections, number of loads per connection, and give understandable results – actually useful! Anyone who develops wants to know how much stress (how many visitors) their application can withstand and how it will perform under a real world load.

My OS is Ubuntu (Natty atm), and apt makes it easy to install by just typing:

gmilby@mini64:~/Dropbox$ sudo apt-get install apache2-utils

1. Number of simulated connections – this simulates the number of visitors to your webapp, and if there are bugs and code errors, it will result to a very poor performance in actual deployment which can slowed down if there are a lot of users in your website.

2. Number of simulated concurrent users – these are the actual number of users that are using the application at exactly the same time. Of course in a very low traffic website, the concurrent users is almost zero because the probability that two users will exactly hit the application and do the same request is very small. This can be an issue with high traffic websites; it is because the number of concurrent users can slowed down the application and put a significant load on the web server. Some web host even limits the number of concurrent users (typically those that are originating from a free web hosting scheme).

Having the ability for the average developer to have access to such a tool as this enables them to be able to at least be aware of potential problems, and can give the developer enough time to research alternate coding methods. It can also shape the actual development. If you start using a huge framework, and realize how much bulk is being carried along to deploy a small app – it may be best to scale it down – look for a more practical approach. Knowing how your site will perform through every stage can save valuable time and embarrassment.

<code>ab -n [number of simulated connections] -c [number of simulated concurrent users] [url]

ab -n 3000 -c 3 http://mall.syrbot.com:81/ > main-mall-results.txt (it is not required, but i like to have a copy of my test results - to refer to)

 

</code>

This is ApacheBench, Version 2.3

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking mall.syrbot.com (be patient)

Server Software: nginx/0.7.67

Server Hostname: mall.syrbot.com

Server Port: 81

Document Path: /

Document Length: 16447 bytes

Concurrency Level: 3

Time taken for tests: 160.446 seconds

Complete requests: 3000

Failed requests: 0

Write errors: 0

Total transferred: 49821000 bytes

HTML transferred: 49341000 bytes

Requests per second: 18.70 [#/sec] (mean)

Time per request: 160.446 [ms] (mean)

Time per request: 53.482 [ms] (mean, across all concurrent requests)

Transfer rate: 303.24 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 39 53 95.0 49 3051

Processing: 81 108 88.1 107 4670

Waiting: 41 53 10.5 53 335

Total: 125 160 129.9 157 4720

Percentage of the requests served within a certain time (ms)

50% 157

66% 162

75% 165

80% 167

90% 172

95% 177

98% 188

99% 207

100% 4720 (longest request)

These results show that the longest render of the website took 4720 milliseconds. Which is not bad considering it is the bottom of the line VPS, and pushing a ton of jQuery, Python and CSS for each page render (all 3000 requests!). the average was 157 milliseconds – so my choice to use NGINX to serve and Bjeorn pure C wsgi server turned out to be a good choice this time.

You can bet I will be using this from here on out. It helps me to know that new technologies may be reliable. It’s easier to trust a technology if you know the load it can stand.

No Comments

jQuery tmpl() Part 1. (The No Nonsense Version For New jQuery Templates)

Written by Gregory Milby | Tuesday, April 19th, 2011

It seems like some people can just be near a book about something ‘new’, and somehow absorb enough of it to make do. Unfortunately, I am not one of those people. When learning something new, it’s my preference to be able to do some basic things (manipulating string, simple data structures, and basic-type operations with a database or a data-structure of some sort) before openly admitting to myself that it’s possible to ‘use’ a new technology.

Add to this self-imposed regiment of learning, the process of absorbing something new – still in Beta, and the craziness factor goes up a few levels… While my chops are getting proofed, the developer is not even  finished – the plugin isn’t solidified and ready for release!

jQuery templates (tmpl()) is one of these type of endeavors.  The functionality is there, but nothing is set in stone yet. However, these are the basic concepts that are not published anywhere at the moment.

The basic premise is you get a piece of data, a json string.  In jQuery, a data string look like this: (notice the “[" & "]” on each end of the string)

[{"id":"1","title":"Home","content":"Home Page...\r\nLorem ipsum dolor sit amet, ","region":"main","display":"1"}]

Don’t let this get confusing off the bat. It is EXACTLY just like a row from a database table. Look closer at the first few pieces:

[{

"id":"1",

"title":"Home",

"content":"Home Page...

No surprises... it's just the column name, and the data that it has assigned to it.

When javascript (jQuery) passes a json string, it is wrapped in the braces ("[ ... ]"). The jQuery tmpl() method strips these off (for our convenience, or for functionality of jQuery - no one was able to give a definitive answer on that question), but when we work with this json string, it will be a pure piece of data thanks to the braces being stripped off.

This may seem like a tedious approach, but if you want to do more than just sling a string at your front end, then you'll want to know what it is you're controlling (the data).

For now our data looks like this:


data = var people = [
{
firstName: "John",
lastName: "Doe",
}
];

we're doing 'onesies' before going nuts and adding more data!

An easy way to think of this is, we have our data. We have a var named, "people", and it has one object (one key and one value).  If you output people.firstName, it will equal "John".  If we output people.lastName, it will equal "Doe".

When working on something 'new', it's good to use the latest CDN (content delivery network) version of the scripts. As it turns out, this is wise, considering tmpl is still BETA - it's nice to know if something "I KNOW" worked, stops working due to a change in the code plugin.

The next step is to make a function to extract the data we want to extract from the string.


function getFirstName() {
return this.data.firstName;
}

When 'getFirstName()' is executed, it will get look at the data we've predefined. You've probably guessed that we could get lastName with such a function too? (you're right!).  Regardless of how much data was defined in the structure, we could extract it this way.


$(function(){
$( "#tmplPeople" )
.tmpl( people )
.appendTo( ".peopleTable" );
});

Before tip the box over and let you look in, it may be best to explain what 'will be happening' when it all fires.

This function will look for a defined template called, "#tmplPeople". it will look at your predefined data (people - of which we have one entry for now). It will take the data, place it into the template (named tmplPeople) and then snap it into the peopleTable. S0,  our one data entry, will be formatted, then put into the html table.


<script id="tmplPeople" type="text/x-jquery-tmpl">
<tr>
<td colspan="2">${getFirstName()} </td>
</tr>
</script>

<table><tbody></tbody></table>

here is our <table>, that will house the templates after the data is parsed by the function we looked at above. Right above the <table> is our template we labled "tmplPeople". As you can see, each time that template is called (tmplPeople), it is going to call our 'getFirstName' function, and it is going to take the first name from our data, and populate it into the template, then it will add it to the table.

Here is the whole code snippet, if this generates any feedback, we'll continue onto the many other ways to parse data from json!


<script src="http://code.jquery.com/jquery-latest.min.js"></script>
 <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>

<script type="text/javascript">// <![CDATA[


function getFirstName() {
return this.data.firstName;
}

function getLastName() {
return this.data.lastName;
}

$(function(){
$( "#tmplPeople" )
.tmpl( people )
.appendTo( ".peopleTable" );
});

// ]]></script>

<script id="tmplPeople" type="text/x-jquery-tmpl">// <![CDATA[


<tr>
<td colspan="2">${getFirstName()}  ${getFirstName()}</td>
</tr>

// ]]></script>
<table>
<tbody></tbody>
</table>

4 Comments