How Upgrading to PHP 7 Boosted Our Site Performance by Up to 50%
This article details Baixing.com's migration to PHP 7, covering the performance gains, deployment steps, code incompatibilities, extension upgrades, and practical tips that together reduced server load and page response times by 30‑50%.
Background
From Bird's 2015 QCon talk we learned that PHP 7 is a major rewrite of the engine, optimizing zval structures, function call mechanisms, and memory management, resulting in a qualitative performance leap. After several stable releases, most common extensions are compatible, making the upgrade timing mature.
With Baixing.com's rapid business growth, the backend architecture became increasingly complex and page response times slowed, hurting user experience. Over the past months we focused on performance optimization, and upgrading to PHP 7 proved effective: backend server load and core page response times dropped by 30%‑50%.
CPU usage change:
Page response time change:
Deployment Plan
Baixing.com uses three environments: offline development, pre‑release, and production. A typical case follows these steps: develop and test locally, deploy to pre‑release for QA testing, then roll out to production. The PHP 7 upgrade followed the same progression:
Upgrade the offline development environment (extensions and code) and let developers and QA test.
Upgrade the pre‑release environment and run tests.
Perform a gray‑scale rollout in production, monitor stability, then fully upgrade.
Remember to disable Transparent HugePages (THP), which can cause PHP 7 to consume 100% CPU. Disable it with:
echo never > /sys/kernel/mm/transparenthugepage/enabled
echo never > /sys/kernel/mm/transparenthugepage/defragPHP Code Upgrade
PHP 7 maintains 99% backward compatibility, but indirect variable, property, and method references are now evaluated left‑to‑right. Example incompatibilities:
$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
$foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
$foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()To retain PHP 5 behavior, wrap the expression in braces:
${$foo['bar']['baz']}
$foo->{$bar['baz']}
$foo->{$bar['baz']}()
Foo::{$bar['baz']}()We recommend using php7cc for automated compatibility checks and have integrated it into our build pipeline.
Some API changes to note: json_decode() now strictly follows the JSON standard; control characters cause errors. Escape them first, e.g.:
{
"msg": "PHP 是世界上最好的语言
没有之一"
}From PHP 5.6, the Mcrypt extension requires keys of 16, 24, or 32 bytes. Since Mcrypt is deprecated in PHP 7.2, replace it with OpenSSL:
mcrypt_decrypt(MCRYPT_3DES, KEY, $data, "ecb");
// replace with
openssl_decrypt($data, 'des-ecb', KEY, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);Extension Upgrade
Most extensions have PHP 7‑compatible versions, but the upgrade required considerable effort:
Remove unused extensions.
Upgrade extensions that already support PHP 7 (e.g., ext‑memcached, ext‑redis).
Replace unmaintained or incompatible extensions such as xhprof and ext‑mongo.
MongoDB's old ext-mongo only supports PHP 5.x, so we switched to ext-mongodb, which has an incompatible API and required code rewrites. For serialization (e.g., Memcached caching) we updated data classes accordingly. Installation example:
wget https://pecl.php.net/get/mongodb-1.3.0.tgz
tar xf mongodb-1.3.0.tgz
cd mongodb-1.3.0
phpize
./configure --without-mongo-sasl
make installIf serialization is not needed, the mongo-php-adapter can act as a drop‑in shim, reducing migration effort.
For ext-memcached, the new version changes getMulti() behavior: it returns false on timeout instead of partial results. We mitigated this by batching keys in groups of 30:
public function getMulti(Array $keys) {
...
foreach (array_chunk($keys, 30) as $subKeys) {
$ret += $this->client()->getMulti($subKeys);
unset($subKeys);
}
...
return $ret;
}We also replaced Facebook's XHProf with Tideways for profiling. Installation steps:
git clone https://github.com/tideways/php-profiler-extension.git
cd php-profiler-extension
phpize
./configure
make
sudo make installThen add to php.ini:
extension=tideways.so
tideways.auto_prepend_library=0Pairing Tideways with XHGui allows storing profiling data in MongoDB and provides a convenient web UI.
Conclusion
The PHP 7 migration presented several challenges, but through collaborative effort we resolved them and achieved significant performance gains. The team is excited about the results and looks forward to PHP 8's JIT features. If you haven't upgraded yet, now is the time to act.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Baixing.com Technical Team
A collection of the Baixing.com tech team's insights and learnings, featuring one weekly technical article worth following.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
