Over the last four weeks, I’ve been plagued by numerous PHP segfault problems – multiple versions of PHP, on different operating systems, on different hardware, and running completely different codebases.

Yesterday, I ran into a segfault that I couldn’t work around. It is happening with Apache + mod_php, running inside a Centos 6-based Docker container. Docker is hosted on Ubuntu 15.04.

Here are the steps I took to enable core dumps for Apache inside the container, so that I could examine the segfault.

On Ubuntu (the host machine):

  1. sudo sysctl -w fs.suid_dumpable=2
  2. sudo sysctl -w kernel.core_pattern=/tmp/core-%e-%s-%u-%g-%p-%t

That’s it. Your Docker container automatically inherits these settings, and Apache will start coredumping without being restarted.

Why Does This Work?

With Docker, because it’s not a virtual machine in the way that VMWare or VirtualBox is, the container inherits the settings of your host operating system. Inherits, and can’t change them inside the container (which is not ideal).

You have to enable coredumps on your host operating system.

Ubuntu 15.04 ships with coredumps already enabled. Ubuntu also ships with an app that gathers coredumps and ships them off to Canonical for inspection – this is the ‘A system error has been detected’ dialog box that appears all too frequently on a modern Ubuntu system.

Ubuntu’s helper app can’t intercept coredumps that occur within a Docker container, so you don’t have to worry about it in there.

Be the first to leave a comment »

I’ve given several talks to user groups over the last few months, around the topics of testing and performance. I hope that you find them interesting and useful.

When To Mock

Mocking has not only become a mainstream practice in recent years, it has also become the default practice for many developers. In this talk, I present three questions that you should ask yourself first whenever you’re deciding if a mock is the right way to test your code, and some insight into how over-mocking ends up making your tests no better than having no tests at all.

This talk was presented to PHP Dorset in November, 2014.

How Much Does Your ORM Cost?

Whenever you use an ORM, you’re trying to reduce the time it takes to ship your code. But what are you trading in return? This lightning talk introduces the idea that ORMs aren’t entirely “free”, and hopes to start you thinking about how you might go about measuring just how much that ORM is really costing you.

This talk was presented to PHP South West (where I was once the answer to a pub quiz question – my claim to fame!) in April 2015.

The Mad Science of Testing

I’m a firm believer that good testing is also good science, and in this talk, I hope to convince you too. And if we’re going to be scientists, we might as well be mad scientists, because they have all the fun 🙂

This talk was presented to PHP Berkshire in June 2015.

Be the first to leave a comment »

At work, we’ve recently published HubFlow: instructions + tools for using Vincent Dreissen’s GitFlow model with GitHub.

The full article is over on the DataSift dev blog.

2 comments »

Whether you’re looking at your own code before (or after!) you have shipped it, or you’re picking up someone else’s code after they have shipped it, tracking down and fixing bugs is a fundamental part of programming. If you know the code well, perhaps you can make an intuitive leap to immediately jump to where the bug is. But how do you go about tracking down a bug when intuition doesn’t help?

The nature of all code is that larger systems are built from smaller underlying systems and components. They in turn are also constructed from smaller components. The bug you are tracking down will have a cause in one of these systems, and will have symptoms that are visible in other systems. The remaining systems work fine (as far as the bug you’re looking for is concerned), and you can use this to quickly and reliably find where the bug is.

Divide your larger systems down into smaller systems at logical points, such as different server stacks, APIs, major interfaces, classes, methods and if necessary individual lines of code. Test both sides of the divide, with your tests focusing on the data that crosses the divide. If one side works as expected, the bug is not in there, and you can eliminate that side from further testing. Continue testing the remaining systems and components, which you have now isolated, by dividing those up into smaller systems and components. Keep going until you’ve reached the smallest testable system, component, unit, or lines of code that show the fault. Congratulations: you have isolated the fault.

Apart from being a strategy that allows you to work on code you’ve never seen before, this approach also has the advantage that it is evidence-based. This approach eliminates guess work, and it forces developers’ assumptions about how their code actually works in practice to be challenged. The data never lies, but be aware that it can be mis-interpreted!

The approach is iterative, and you’ll find that you’ll often go back and forth between your code and your tests, making your code easier to test and your tests have clearer and more targeted test domains and results. Fix the tests that are relevant to the bug you are tracking down, and make a list of any other issues you find along the way for you to come back and address at a later date. Stay on target, and park potential tangents and distractions for another time.

Although this sounds like a slow process when described on paper, with practice it can be executed at high speed during an emergency situation. However, the need to restore service in a timely manner isn’t always compatible with this approach, and you’re normally better off returning to your test environment where you can study the fault without inconveniencing your customers any further.

Be the first to leave a comment »

I was just reading Derick’s post about the recent get together with Microsoft, and it occurred to me that so far, I haven’t seen anyone mention anything about the single most important problem with running PHP in production on IIS. After a bit of digging, it looks like the problem has been sorted since the initial IIS 7 release (presumably, if you’re still running Windows Server 2003, you’re still screwed on this one), but I’d love to hear from folks who have definitely done this in production.

Let me explain the background first. When you run PHP apps using IIS, you’re much better off using IIS’s native CGI support (slow, but rock-solid as of Windows Server 2003 SP1) or the new FastCGI support that was released last year or the year before (faster, but I haven’t tested it personally under serious stress, as I’ve managed to move back to working exclusively on Linux this year). I’ve tried PHP via IIS’s ISAPI interface, but as that requires running PHP in a threaded environment, I’ve never had any luck in getting it working in a stable manner over the years. Besides, iirc, both Microsoft and Zend recommend running PHP using FastCGI on IIS anyways.

Running PHP via CGI and FastCGI means that IIS has to do the Windows equivalent of fork()ing off PHP processes to do the actual PHP bit. If your box has too many PHP processes running, the box will start to swap. Once a webserver starts swapping, you’ve no chance in hell of keeping up with all the incoming requests, and your websites on that particular webserver become unavailable in a matter of moments. Restarting IIS will clear off all the PHP processes, but if demand remains the same, the webserver will start swapping again very soon and you’re back to square one – your websites back to being unavailable to the outside world.

With Apache and mpm-prefork, mpm-peruser or mpm-itk, you can adjust Apache’s settings to make sure that your server never swaps. With Apache and PHP/FastCGI, you can do this too by adjusting the number of FastCGI processes created. (Although, atm, I don’t recommend using Apache + PHP/FastCGI in production environments).

But how, exactly, do you do this with IIS and PHP/CGI or PHP/FastCGI? The answer can be found in the IIS 7 documentation. It looks like you can limit the number of FastCGI instances per application pool (IIS best practice is to setup a separate application pool per website. IIS’s architecture is nothing like Apache). That’s fine for servers running just the one website, but is there a way to set a similar limit that applies across all application pools? It would be great if there was. And I’m not sure that there’s a way to do this with CGI, if you have problems with FastCGI crashing.

Love it or hate it, Windows Server is the right choice for many firms, and the better PHP runs in a Windows Server production environment, the more opportunities there are for firms and individuals that create PHP apps in the future.

Be the first to leave a comment »

The challenge with securing a shared hosting server is how to secure the website from attack both from the outside and from the inside. PHP has built-in features to help, but ultimately it s the wrong place to address the problem.

I’ve already written about a number of solutions that work, but one option I’ve been asked time and time again to look at is using PHP + FastCGI. The belief is that using FastCGI will overcome the performance issues of Apache’s suexec or mod_suphp, because FastCGI processes persist between page views.

But before we can look at performance, the first question is: how exactly do we get PHP and FastCGI running as different users on the one web server in the first place?

Installing And Configuring mod_fcgid for Apache

Stock Apache does not ship with built-in support for FastCGI. You need to download and install a third-party module. There are two choices – the original mod_fastcgi, and the more recent mod_fcgid, which I’ll look at in this article. Before we start, make sure that you have built and configured Apache to use suexec. We will reuse suexec to ensure that our FastCGI PHP processes run as different users.

Most Linux distributions already include a package for mod_fcgid; you should be able to install it using your distro’s package manage. The version I’ve tested for this article is mod_fcgid 2.2 running on Seed Linux (a Gentoo-based distro).

After installing mod_fcgid, make sure that you edit your Apache config files, and comment out any lines that load mod_php. They will look like this:

LoadModule php5_module modules/libphp5.so

Then, add the following lines to your virtual host.

SuexecUserGroup myuser mygroup

<Directory /var/www/localhost/htdocs>
AddHandler fcgid-script .php
Options ExecCGI
Allow from all
FCGIWrapper /var/www/localhost/cgi-bin/php.fcgi .php
</Directory>

Replace “myuser” with the user who owns the website, and replace “mygroup” with the group that the user belongs to. This sets the privileges that PHP will run as when this website is visited.

Because suexec is understandably paranoid about what CGI programs it will run for you, to make mod_fcgid work in a shared hosting environment, we need to create a FastCGI wrapper script owned by the same user that owns the website:

#!/bin/bash
PHPRC=/etc/php/apache2-php5
export PHPRC
PHP_FCGI_CHILDREN=4
export PHP_FCGI_CHILDREN
PHP_FGCI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
exec /usr/lib/php5/bin/php-cgi

Each website needs its own copy of the script. Place this script in the website’s dedicated cgi-bin directory. This should be a directory that you control to make sure that malicious scripts cannot be uploaded to take advantage of suexec. Make sure that the script is owned by the user and group who owns the website, otherwise suexec will refuse to run the script, and you’ll spend quite a bit of time scratching your head wondering what the problem is!

The FastCGI wrapper script gives us an opportunity to set limits on how PHP works as a FastCGI process. We can tell it how many FastCGI scripts are allowed to run (to make sure one website doesn’t use up all of the web server’s free capacity), and also how many HTTP requests each FastCGI process should handle before terminating (to limit the impact of memory leaks).

At this point, you can restart Apache, and you should find that your websites are now using suexec + FastCGI to run as separate users.

Making Apache Go Even Faster

One of the major benefits of using Apache 2.2 over Apache 1.3 is the ability to switch how Apache works at the fundamental level. Apache MPMs (multi-processing modules) can emulate Apache 1.3’s behaviour (mpm-prefork) … but it can also provide new options. By default, most (if not all) Linux distributions install Apache 2.2 built with mpm-prefork, but by switching to another MPM, can we make our websites go even faster?

If you are using suexec + mod_fcgid on Linux, there are two MPMs available to you that have the potential to boost performance further: mpm-worker and mpm-event. Both MPMs turn Apache into a multi-threaded server. On Linux systems, it is usually much quicker to create new threads than it is to create new processes. The downside is that software has to be specially written to work correctly in a multi-threaded application (known as being thread-safe). mod_php doesn’t work reliably with mpm-worker and mpm-event, because it reuses a lot of third-party code that may or may not be thread-safe. But because we’re running PHP in a separate FastCGI process, we can safely turn Apache into a multi-threaded server.

Some Benchmarks

To benchmark PHP + FastCGI + suexec, I used Apache s ab benchmark to load a simple phpinfo() page 1,000 times. I ran the benchmark five times, and averaged the results. To compare the results, I repeated the tests against mpm-worker, mpm-event, and mpm-prefork both with and without mod_php.

  • mpm-worker + mod_fcgid + PHP/FastCGI + suexec: 7.36 seconds, 0.2% failure rate
  • mpm-event + mod_fcgid + PHP/FastCGI + suexec: 7.75 seconds, 0.2 % failure rate
  • mpm-prefork + mod_fcgid + PHP/FastCGI + suexec: 7.92 seconds, 0.2% failure rate
  • mpm-prefork + mod_fastcgi + PHP/FastCGI + suexec: 8.52 seconds, 0.2% failure rate
  • mpm-prefork + mod_php: 7.38 seconds, 0% failure rate

Other Considerations

The performance is good, especially if you switch Apache MPMs. These benchmarks are extremely simplistic, and what they don’t show is that switching to mpm-worker and mpm-event will probably speed up your websites even further, because these Apache MPMs handle downloading images more efficiently than mpm-prefork can. You may also be able to scale your websites better before having to upgrade your servers or add additional ones, especially if you use a bytecode cache such as APC or xcache.

But what are the downsides?

  • As with straight suexec, you can’t use HTTP authentication in your application. Hardly any apps rely on this functionality any more (probably because so many shared hosting servers use suexec).
  • Your server may require extra RAM to cope with the number of FastCGI processes running simultaneously. You may need to switch to a 32-bit Linux kernel that supports PAE or to a 64-bit Linux distro.
  • Apache + PHP/FastCGI is not 100% reliable in my testing.

Conclusions

It is possible to combine PHP, FastCGI and suexec to produce a solution that secures a shared hosting server and at the same time provides good performance compared to the alternatives. If you’re prepared to compile Apache from source and switch MPMs, you can squeeze even more performance from this combination, and perhaps even out-perform the venerable mod_php.

Unfortunately, my experience was that the PHP + FastCGI combination cannot be trusted to serve pages 100% of the time. The average failure rate was 2 requests per 1000, and the failure rate was consistent no matter which Apache MPM was used, which Apache FastCGI module was used, and how many thousands of requests I used in my testing. At the time of writing, I haven’t tracked down the cause of this failure, and it may not appear in your own environment, but none of the previous solutions I’ve looked at in this series have displayed this problem, so it’s something to think about before chosing PHP + FastCGI to serve your websites. I’m hoping to find time in the future to get to the bottom of this problem, if no-one gets there first.

As a result, I can’t recommend using PHP/FastCGI + suexec at this time. My current recommendation is mpm-itk, which has successfully served millions of page hits for me in production over the last few months.

References

This article was made possible by information already on the internet:

This article is part of The Web Platform, an on-going series of blog posts about the environment that you need to create and nurture to run your web-based application in. If you have any topics that you d like to see covered in future articles, please leave them in the comments on this page.

14 comments »

… as recommended by readers of Planet PHP 🙂

Most Recommendations

There were six Firefox extensions that folks repeatedly recommended …

  1. ColorZilla – advanced eyedropper, color picker, page zoomer and other colorful goodies.
  2. FireBug – live DOM & CSS inspector. The single greatest web developer add-on for Firefox.
  3. Live HTTP Headers – view HTTP headers of a page and whilst browsing.
  4. Web Developer Toolbar – adds a menu and a toolbar with various web developer tools.
  5. YSlow – Yahoo’s tool for analysing web pages and telling you why they are slow. Requires Firebug.
  6. Zend Studio Toolbar – debugging assistance for Zend Studio 5.5 and earlier. Isn’t mentioned on the Zend Studio 6 pages, so does that mean it is now obsolete?

… and after that, there was a lot of variety amongst the other extensions that were recommended.

Also Recommended

  1. Cache Status – easy cache status & management from the status bar.
  2. ChatZilla – IRC client for Firefox.
  3. Duplicate Tab – clone a tab along with its history.
  4. Edit Cookies – edit your cookies right in Firefox.
  5. Fasterfox – performance and network tweaks for Firefox.
  6. Firefox Accessibility Extension – test your web pages for functional accessibility features based on the iCITA HTML Best Practices.
  7. FirePHP – print to your Firebug console using a simple PHP function call.
  8. FireShot – take screenshots of web pages, and a whole lot more.
  9. Google Toolbar – Google’s famous in-browser search toolbar.
  10. GreaseMonkey – customise the way a web page displays using your own Javascript add-ons. See also Lifehacker’s Top 10 Greasemonkey User Scripts, and their Better GMail and Better Flickr add-ons to get an idea of just what can be done with Greasemonkey as a Firefox extension tool.
  11. HTML Validator – add HTML validation to your browser.
  12. IE Tab (Windows only) – open Firefox tabs using IE’s rendering engine. See also the popular IE View alternative.
  13. LocationBar2 – adds additional features to Firefox’s address bar.
  14. Lorem Ipsum content generator – Generate “Lorem Ipsum” dummy text, for when you need to fill a page with content for testing purposes.
  15. MeasureIt – draw out a ruler to get the pixel width and height of any element on the web page.
  16. NagiosChecker – see the status of your services and servers in Firefox’s status bar. You do monitor your servers, right? 😉
  17. PrefBar – power user toolbar for Firefox.
  18. Regular Expressions Tester – testing tool for regular expressions with colour highlighting.
  19. RefSpoof – easy spoofing of the HTTP referrer header.
  20. ReloadEvery – reloads a web page every so many seconds.
  21. Save Session – save your current browser windows & tabs for the next time you open Firefox.
  22. Scrapbook – save web pages locally and easily manage collections. (Like OS X web archives, as supported by Together, DevonThink, and so on, but cross-platform).
  23. Selenium IDE – record, edit and debug tests for Selenium, the automated UI testing tool for web developers. See also PHPUnit’s support for Selenium. You do have reproducible testing for you web apps, right? 😉
  24. Stylish – fix ugly sites, customise the look of your browser or mail client by using your own CSS files. Stylish is to CSS what Greasemonkey is to Javascript.
  25. Tab Mix Plus – tab management on steroids.
  26. Tamper Data – view and modify HTTP/HTTPS headers and POST parameters.
  27. TimestampDecode – treats the selected number as a timestamp and displays a decoded date/time.
  28. TitlebarTweaks – tweak Firefox’s titlebar text.
  29. User Agent Switcher – Adds a menu and a toolbar button to switch the user agent of the browser.
  30. Venkman – Javascript debugger for Firefox.

Stu’s Recommends

To round off the list, here are a few extensions that I find useful, but which weren’t recommended. If you haven’t heard of these before, give them a try.

  1. Flagfox – display a country flag in the status bar for the location of the current website’s server.
  2. Server Switcher – easily switch between development and production servers.
  3. Show MyIP – display your current external IP address.
  4. SQLite Manager – Manage any SQLIte database on your computer.

Are you a web developer? Got a favourite Firefox extension that isn’t on this list? Let us know in the comments below.

Be the first to leave a comment »

The folks from Packt Publishing recently sent me another of their books to review. If you’re not familiar with Packt, they’re a relatively new book publisher who are steadily building up quite a range of technology books on open source software, normally written by people involved or close to the software being written about. They’re like a modern day equivalent to the old O’Reilly of the 90’s, only (imho) with higher quality 🙂

A Bit About Packt

Mastering phpMyAdmin 2.11 for Effective MySQL Management by Marc Delisle is the third edition of this book, and it follows the usual pattern of Packt Publishing books. The book has clearly defined objectives on the cover, and it follows a clear progression of its chosen subject from start to end. It is well presented, with a clear layout and clean page design that makes it easy to read. The book also includes a sizeable index, something no decent technical book can be without.

I’m really pleased to see that Packt are now providing example code online for download, as well as online errata for the book. Many of their earlier books reviewed here on Planet PHP have been criticised for not doing so; it’s great to see Packt improving in this area.

No matter which Packt book you pick up, don’t let the use of language be the reason you put it back on the shelf. Most Packt books are written and reviewed by folks who don’t speak English as their first language. Once you get used to it, it’s never really a problem, but it’s worth pointing it out because if you browse their books at your local bookstore, it might put you off at first.

Introducing phpMyAdmin

If you’ve never heard of it, phpMyAdmin is (imho) one of the most important open source projects for the LAMP stack. phpMyAdmin provides a web-based admin interface for MySQL, making it extremely easy for folks new to the LAMP stack to start working with databases, and a very convenient way to avoid firing up the MySQL command-line if you need to check something or make changes to your databases.

It feels like phpMyAdmin has been around forever.

Unfortunately, it looks that way too at times. In the post Google Maps world of AJAX enabled slick and efficient user interfaces, phpMyAdmin’s usefulness can be hampered by its Web 1.0 UI, and by its continued reliance of manual configuration instead of a WordPress-like admin panel. Don’t get me wrong, phpMyAdmin is a good tool without equal atm, but it’s a workmanlike and functional tool that younger folks used to the Facebook world find a bit long in the tooth.

About The Book

Marc’s book is aimed both at folks new to MySQL and phpMyAdmin as well as experienced developers such as myself who aren’t aware of the advanced features that have been added over the years. The full chapter list is:

  1. Introducing phpMyAdmin
  2. Installing phpMyAdmin
  3. Interface Overview
  4. First Steps
  5. Changing Data
  6. Changing Table Structures
  7. Exporting Structure and Data
  8. Importing Structure and Data
  9. Searching Data
  10. Table and Database Operations
  11. The Relational System
  12. Entering SQL Commands
  13. The Multi-Table Query Generator
  14. Bookmarks
  15. System Documentation
  16. MIME-Based Transformations
  17. Character Sets and Collations
  18. MySQL 5.0 Features
  19. MySQL Server Administration
  20. Troubleshooting and Support

The first ten chapters cover the basics of using phpMyAdmin. If you’re new to phpMyAdmin, these chapters will be very helpful to you, and if you’ve been using phpMyAdmin for years, there’s still little bits in here that you might not have been aware of before now. I particularly like the way that these chapters often refer back to the configuration settings in phpMyAdmin’s config file. However, towards the end of this section, the material starts to feel a bit rushed, as if the author himself can’t wait to get onto the clever features of phpMyAdmin that have yet to come. If you’re completely new to MySQL, you might find the end of this section to be a little light on detail. I hope the next edition of this book beefs these chapters up a bit.

Like most people I know, my use of phpMyAdmin over the years has tended to stick with the basics: creating and browsing tables. I confess, it’s partly because I’ve found the phpMyAdmin UI to be more and more clunky as time has gone by, a throwback to the days before Google showed us just what could be done with Javascript and AJAX. So the second half of the book, which looks at the more advanced features of phpMyAdmin, were ones I found very educational. I had no idea, for example, that phpMyAdmin now includes an AJAX-based Designer tool, or that I can use phpMyAdmin to generate PDF documentation of my databases. I found these chapters to be very detailed and informative, although again towards the end of the second half of the book, the chapters began to feel a little rushed in places to me.

Conclusion

I have several new starters joining my team in June, and it’ll be interesting to see whether or not they find the book useful as they find their feet in their first job doing PHP web development. One thing’s for sure: I’ll have no hesitation in leaving this book out for them to read.

4 comments »

This Month

September 2017
M T W T F S S
« Jul    
 123
45678910
11121314151617
18192021222324
252627282930