Slide 1

Slide 1 text

Writing Portable PHP - DREW MCLELLAN - - CONFOO 2015 -

Slide 2

Slide 2 text

Hello! flickr.com/photos/85520404@N03/9535499657

Slide 3

Slide 3 text

Perch CMS PHP & MySQL content management system. ‘WordPress model’ - download and install on your own hosting.

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Listen up! This session is about shipping code into uncontrolled environments. It’s about coping with restrictive hosting, old PHP versions, lack of dependancy management and how PHP is working against us. It probably poses more problems than solutions. It may turn into a self-help group.

Slide 6

Slide 6 text

You can switch. This session probably won’t help if your code is deployed with Composer. My tips are of no use to you if your answer to PHP 5.3 is to tell your user to upgrade. If your solution to a missing dependancy is to install the dependancy, I have nothing for you. You can switch rooms, we’re all friends here.

Slide 7

Slide 7 text

Are we good?

Slide 8

Slide 8 text

We love to hate PHP

Slide 9

Slide 9 text

60% - CMS USE - 23% - ALL WEBSITES -

Slide 10

Slide 10 text

This is common By numbers, the ship-and-deploy-to-bad-hosting model is the most common way PHP code is deployed. Despite this, PHP is actively hostile to this way of working.

Slide 11

Slide 11 text

PHP is architecturally ill- suited for shipping code. Half-baked modularity! Configuration without detection! Offloading functionality to host OS! Non-standard as standard!

Slide 12

Slide 12 text

PHP versions

Slide 13

Slide 13 text

PHP versions 13 25 38 50 5.2 5.3 5.4 5.5 5.6 2% 12% 45% 35% 7% - PERCH CMS USERS -

Slide 14

Slide 14 text

Hosts don’t like to update PHP Historically, PHP updates have caused incompatibility with common software. Hosts are nervous to update a server, break sites and anger their customers. But they’re usually happy to move a customer to a newer server with newer PHP on request.

Slide 15

Slide 15 text

PHP has to move forward.

Slide 16

Slide 16 text

ext/mysql 1. Hosting company tests PHP 7, looks good. 2. Deploys PHP 7 on new servers. 3. New customers migrate old sites to new hosting. 4. Sites don’t work. Tech support freaks out. 5. Host considers PHP 7 unsafe, rolls back to PHP 5. 6. Five more years of winter.

Slide 17

Slide 17 text

If you ship code, you have to deal with old PHP - AND NEW PHP -

Slide 18

Slide 18 text

Safe mode Deprecated in PHP 5.3, removed in 5.4 Don’t rely on being able to keep files outside of the web root. Don’t rely on reading a file unless you created it. cURL requests with follow_location option fail. Non-standard as standard!

Slide 19

Slide 19 text

Magic Quotes Deprecated in PHP 5.3, removed in 5.4 Was a misguided security feature. Designed without considering portability. Continues to me an enormous PITA. Non-standard as standard!

Slide 20

Slide 20 text

Magic Quotes That’s life. That\’s life. That’s life.

Slide 21

Slide 21 text

Magic Quotes str.replace(‘this\’n\’that’) str.replace(\’this\\\’n\\\’that\’) str.replace(‘this\’n\’that’) str.replace(‘this’n’that’)

Slide 22

Slide 22 text

Magic Quotes So we just need to ask PHP if magic quotes have been applied to the input… … oh wait. get_magic_quotes_gpc(); get_magic_quotes_runtime(); Configuration without detection!

Slide 23

Slide 23 text

Mixed PHP versions Your code might run on different PHP versions between development and live environments. Web requests and CLI might use different versions. It’s not enough to configure, you have to detect.

Slide 24

Slide 24 text

Mixed PHP versions

Slide 25

Slide 25 text

Modularity - HALF-BAKED -

Slide 26

Slide 26 text

Modularity issues Common functionality is provided by optional extensions. Missing extensions can’t be dynamically loaded. Core functionality can be disabled. No structured way to test the environment.

Slide 27

Slide 27 text

Using a database Let’s use a MySQL database! We may have mysql, mysqli or PDO. So, mysqli or PDO then. mysqli is optional! PDO is enabled by default from PHP 5.1

Slide 28

Slide 28 text

PDO + MySQL PDO is enabled by default, but can be disabled. PDO’s MySQL driver is optional. Sooooo…

Slide 29

Slide 29 text

Both?

Slide 30

Slide 30 text

SQLite! “PDO and the PDO_SQLITE driver is enabled by default as of PHP 5.1.0.” SQLite DB is just a file, and needs to be kept somewhere safe. PHP provides no mechanism like it does for, e.g. session files.

Slide 31

Slide 31 text

Manipulating images This is something websites do. PHP is for making websites! So PHP can manipulate images, right? Well, we need to talk about that…

Slide 32

Slide 32 text

GD & Imagick Two common extensions: GD and Imagick Usually one or the other, sometimes both or sometimes none. You need code for both: use a library if you can. e.g. http://image.intervention.io

Slide 33

Slide 33 text

HTTP requests PHP is a web scripting language. Let’s make an HTTP request! Yeah, about that…

Slide 34

Slide 34 text

HTTP requests sockets - works! Pretty low level. cURL - optional. High level and useful. file_get_contents() - sometimes works. Basic. Libraries?

Slide 35

Slide 35 text

HTTP libraries Lots of choices - many are just wrappers around cURL. Others offer a transport choice, but no detection (e.g. Guzzle) ‘Requests’ looks good in this regard. http://requests.ryanmccue.info

Slide 36

Slide 36 text

No way to load extensions If something is missing, it’s missing. You can’t load it, import it, require it. You just have to deal with it.

Slide 37

Slide 37 text

Disabling core functionality PHP gives the system admin the ability to disable core functionality that is “always” there. Detecting what’s available is impractically cumbersome.

Slide 38

Slide 38 text

Disabling core functionality

Slide 39

Slide 39 text

Disabling core functionality

Slide 40

Slide 40 text

Disabing other random stuff Remember, sysadmins be crazy. We’ve seen GD available, but imagecreatefrompng() simply missing. Good luck out there.

Slide 41

Slide 41 text

Bad hosting Configuration without detection!

Slide 42

Slide 42 text

Bad hosting Expect the unexpected! Hosts do crazy things for reasons you’ll never understand. Don’t try to understand. Just accept.

Slide 43

Slide 43 text

Sessions Many shared hosts like to give users their own PHP sessions folder. But then leave it up to the user to configure the session_save_path. By default, sessions will start but won’t persist any data.

Slide 44

Slide 44 text

cURL Some hosts will disable or not install cURL, which is their choice. Others will install and enable cURL. A very special third group install and enable cURL and then block it at their firewall.

Slide 45

Slide 45 text

Cross-platform Offloading functionality to host OS!

Slide 46

Slide 46 text

PHP on Windows PHP on Windows is a real thing. It’s used more in development environments than in production. Users will set up WAMP or similar on their Windows desktop, and then deploy to a *nix hosting environment.

Slide 47

Slide 47 text

Paths PHP expects you to know how to formulate file system paths for the host. Sometimes the file system will forgive errors (e.g. slashes vs back-slashes) Sometimes it won’t.

Slide 48

Slide 48 text

Paths Wrap all your paths so they can be translated for the current file system. Then write your paths consistently in one style.

Slide 49

Slide 49 text

Paths

Slide 50

Slide 50 text

Dates Simple date formatting is fraught with danger. strftime() passes through to the host OS. Some formatting codes will work with your host OS. Some will completely fail and return nothing, or throw a notice.

Slide 51

Slide 51 text

Dates I like to define some set formats that I think should work broadly, but let the user redefine them for edge-cases.

Slide 52

Slide 52 text

Dates

Slide 53

Slide 53 text

Watch out for ‘Windows’ Get in the habit of watching out for references to Windows in the PHP manual. It will help you spot potential Windows issues, but also is a warning of functionality that gets passed to the host OS. These will often be affected by configuration, not just platform.

Slide 54

Slide 54 text

File systems and MySQL MySQL is not immune. Don’t mix case in object names (e.g. table names). MySQL’s case sensitivity is dependant on the host file system.

Slide 55

Slide 55 text

Thanks! @drewm