WPDay Bologna 2013
-
Upload
danilo-ercoli -
Category
Technology
-
view
1.259 -
download
1
Transcript of WPDay Bologna 2013
How to become a better WordPress Developer
1
WPDAY - BOLOGNA - SEPTEMBER, 13 2013
DANILO ERCOLI
AGENDA
WPDAY BOLOGNA - SEPTEMBER, 13 2013
• Development Tools
• The WordPress Codex
• Coding Standards
• Data Validation
• wpshell
• Caching
• Debugging
WORDPRESS DEVELOPMENT TOOLS
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEVELOPMENT TOOLS
• A good IDE can help you program faster and better: Sublime Text 2, PHP Storm, Eclipse for PHP, Netbeans for PHP, Coda
•Code completion, easy WordPress function reference, project management, database editing, file comparison, FTP, debugging facilities
•Codex and PHP Manual always loaded in the browser
•Keep a copy of WordPress core in your IDE
•Use wpshell for fast testing. Use command line interface (wp-cli)
• Install XDebug on your local/remote installation (live debugging)
WPDAY BOLOGNA - SEPTEMBER, 13 2013
THE WORDPRESS CODEX
WPDAY BOLOGNA - SEPTEMBER, 13 2013
CODEX
•The WordPress codex, and PHP Manual always under your hands.
• codex: The online manual for WordPress Developers http://codex.wordpress.org
•The Codex is a wiki, meaning anyone can edit it. It grows and thrives off of individual contributions from people like you
•The best starting place for learning about how to develop pluginshttp://codex.wordpress.org/Writing_a_Plugin
•Working with Themes https://codex.wordpress.org/Theme_Development
•WordPress Coding Standards
http://codex.wordpress.org/WordPress_Coding_Standards
General information about coding standards for WordPress development
WPDAY BOLOGNA - SEPTEMBER, 13 2013
CODEX: CODINGS STANDARDS
•Single quotes unless you need to evaluate a variable
<?php echo 'a great string'; ?>
vs
<?php $dog_name = 'Winston';
echo "my dog's name is: $dog_name"; ?>
•Naming is important
$myGreatVariable = 2; //not so much
$my_great_variable = my_function(); //Correct
WPDAY BOLOGNA - SEPTEMBER, 13 2013
CODEX: CODINGS STANDARDS
•Yoda conditionsif ( $city == 'Montreal' )
vs.
if ( 'Montreal' == $city )
•Don’t get too clever
isset( $var ) || $var = some_function();
Easier to read:
if ( ! isset( $var ) )
$var = some_function();
WPDAY BOLOGNA - SEPTEMBER, 13 2013
WPSHELL
WPDAY BOLOGNA - SEPTEMBER, 13 2013
WPSHELL
• wpshell is a command line shell suitable for any php project, includes code indexing, searching, and displaying built-in
• It gives you a command shell that accepts native PHP code as well as all the functionality your regular WordPress install would give you
• http://code.trac.wordpress.org/ - http://hitchhackerguide.com/2011/11/13/wpshell-a-shell-for-wordpress/
• This is intended for advanced developers. If you don’t know what you’re doing you can easily mess up your WordPress install. You can delete posts/users/anything in few commands
• I would not run this on production, but only in a local development environment. We will run it in production on WordPress.com (but rollback is easy there)
• Example: switch_to_blog( 11719333 ); $lastposts = get_posts( 'numberposts=1' ); var_dump( $lastposts );
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEBUGGING
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEBUGGING TECHNIQUES
• echo The simplest approach, useful for seeing what a value is during run-time. This just outputs the value of a variable to a page you’re working on.
• var_dump() / print_r() / var_export()These functions displays structured information of a variable.
• console.log() / alert()If you’re writing Javascript, then you’ll probably be using one of these approaches. Alert will pop up a blocking dialog that you need to confirm to close (be careful about doing this in a loop!) while console.log() will write to your browser’s developer’s console (accessible via Web Inspector, Firebug, etc).
• debug_backtrace The debug_backtrace() function generates a backtrace.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEBUGGING TECHNIQUES
• PHP “Magic Constants”Use PHP macros in combination with your various output techniques, like so: sprintf( "%s: %s", __FILE__, __LINE__ )
Spamming this down a file/function will help you figure out the path of execution, and also the last place your script was before “stopping” It can generate a lot of output but it’s pretty useful at times
• error_log()Instead of outputting a value directly to a page, using this to output it to your sandbox’s (or production) php error log file.
error_log( print_r( $results, true ) );
It’s often handy to have a Terminal window open with the following command running, which will show you the most recent entries in the log:
tail -‐f /tmp/php-‐errors
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEBUGGING TECHNIQUES
• My favorite logging combo
error_log( "Request headers : \n\n".var_export( my_get_request_headers(), true ) );
error_log( "backtrace: \n" . print_r( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT, 2 ), 1 ) );
Request headers :array ('x-forwarded-for' => '151.28.191.79','x-ip-trail' => '151.28.191.79','x-forwarded-port' => '443','x-forwarded-proto' => 'https','host' => 'public-api.wordpress.com','connection' => 'close','authorization' => 'Bearer tra-lallero-trallalà-XXXX','accept' => '/','accept-encoding' => 'gzip, deflate','accept-language' => 'en;q=1, fr;q=0.9, de;q=0.8, ja;q=0.7, nl;q=0.6, it;q=0.5','content-type' => 'application/x-www-form-urlencoded; charset=utf-8','cookie' => 'wordpress_test_cookie=WP+Cookie+check','content-length' => '188','user-agent' => 'wp-iphone/3.7.1 (iPhone OS 6.1, iPhone Simulator) Mobile',)
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEBUGGING TECHNIQUES
debug_backtrace: Array( [0] => Array ( [file] => /home/wpcom/public_html/wp-content/mu-plugins/push-notifications.php [line] => 244 [function] => xmmp_log [class] => Mobile_Push_Notifications [object] => Mobile_Push_Notifications Object ( [log_recipients:Mobile_Push_Notifications:private] => Array ( [0] => [email protected] )
[log_target_users:Mobile_Push_Notifications:private] => Array ( [0] => eritreocazzulati [1] => 7272jean )
)
[type] => -> [args] => Array
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEBUGGING TECHNIQUES
• Email!!Email isn’t dead! You can send debugging information directly to an email account using something like this:
mail( '[email protected]', 'Really Important Debugging Information', print_r( $important_data, true ), 'From: [email protected]' );
Note that I like to use my direct @gmail.com address to get the fastest possible delivery, and setting a From address can help avoid getting these things sent to your spam folder.
•XDebug If you’d like to connect to your ( remote | local ) server from your local machine and use xdebug to get very detailed debug info, breakpoints, etc.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DEBUG PLUGINS
• Debug Bar
http://wordpress.org/extend/plugins/debug-bar/
Adds a debug menu to the admin bar that shows query, cache, and other helpful debugging information.
• Debug-Bar-Extender
http://wordpress.org/extend/plugins/debug-bar-extender/
Extends the debug-bar plugin with additional tabs to measure runtimes between checkpoints and lookup variable content. (Do not use in a production site).
• Debug Bar Console
http://wordpress.org/extend/plugins/debug-bar-console/
Adds a PHP/MySQL console to the debug bar. Requires the debug bar plugin.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
CACHING
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DIFFERENT TYPES OF CACHING
Full page caching
•WP Super Cache•Batcache•W3 Total Cache
Object level caching with native caching APIs
•W3 Total Cache•WP File Cache•APC•Memcached Object Cache
WPDAY BOLOGNA - SEPTEMBER, 13 2013
FULL PAGE CACHE: BATCACHE
What is Batcache?
Batcache is a plugin to store and serve cached versions of rendered pages.
• Batcache uses memcached as its storage and is aimed at preventing a flood of traffic from breaking your site. It does this by serving old pages to new users.
• This reduces the demand on the web server CPU and the database. It also means some people may see a page that is up to 5 minutes old.
•Development testing showed a 40x reduction in page generation times: pages generated in 200ms were served from the cache in 5ms.
• Traffic simulations with Siege demonstrate that WordPress can handle up to twenty times more traffic with Batcache installed.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
PAGE CACHE: BATCACHE
Who receives a cached pageview?
• By default, all new users receive a cached pageview.
• New users are defined as anybody who hasn’t interacted with your domain —once they’ve left a comment or logged in, their cookies will ensure they get fresh pages.
• Note that URLs with query strings are automatically exempt from Batcache.
$batcache['max_age'] = 300; // Expire batcache items aged this many seconds (zero to disable it)
$batcache['times'] = 4; // Only batcache a page after it is accessed this many times.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
PAGE CACHE: BATCACHE
Because Batcache caches fully rendered pages, per-user interactions on the server-side can be problematic.
This means usage of objects/functions like $_COOKIE, setcookie,$_SERVER['HTTP_USER_AGENT'], and anything that’s unique to an individual user cannot be relied on as the values may be cached and cross-pollution can occur.
In most cases, any user-level interactions should be moved to client-side using JavaScript.
In some cases, we can help you set up Batcache variants if you’re limiting your interactions to a small set of distinct groups.(e.g. serve different content for users depending on whether the cookie “customer-type” is set, or equals “paid” or “pending”). Please get in touch if this something you’re interested in setting up.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
PAGE CACHE: BATCACHE
if ( Jetpack_User_Agent_Info::is_blackbeberry() ) {
! $batcache['unique']['mobile'] = 'blackberry';
} elseif ( Jetpack_User_Agent_Info::is_WindowsPhone7() ) {
! ! $batcache['unique']['mobile'] = 'windows-phone7';!
} elseif ( Jetpack_User_Agent_Info::is_S60_OSSBrowser() ) {
! $batcache['unique']['mobile'] = 'dumb';
} elseif ( in_array( jetpack_is_mobile( 'smart', true ), array( 'iphone' ) ) ) {
! $batcache['unique']['mobile'] = 'iphone';
} elseif ( jetpack_is_mobile( 'dumb' ) ) {
! $batcache['unique']['mobile'] = 'dumb';
}
Batcache Variants
WPDAY BOLOGNA - SEPTEMBER, 13 2013
WORDPRESS NATIVE CACHING APIS
Transients
• Persistent out of the box• Stored in wp_options: _transient_{key} • WordPress uses for certain internal functions • set_, get_, and delete_transient()
Object Cache
•Not persistent without a plugin, such as W3 Total Cache or Memcached Object Cache•Storage depends on server's and plugin's capabilities•Used extensively within WordPress Cache objects can be grouped wp_cache_add(), _set, _get, _delete
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DATA VALIDATION
WPDAY BOLOGNA - SEPTEMBER, 13 2013
PROPERLY VALIDATE, SANITIZE, AND ESCAPE YOUR DATA
Your code works, but is it safe?
Rule No. 1: Trust Nobody
The idea is that you should not assume that any data entered by the user is safe. Nor should you assume that the data you’ve retrieved from the database is safe – even if you had made it ‘safe’ prior to inserting it there.
•In fact, whether data can be considered ‘safe’ makes no sense without context.
•Sometimes the same data may be used in multiple contexts on the same page.
Rule No. 2: Validate on Input, Escape on Output
To escape is to take the data you may already have and help secure it prior to rendering it for the end user
WPDAY BOLOGNA - SEPTEMBER, 13 2013
DATA VALIDATION
A must-read for WordPress contributors. Describes the functions used by WordPress to validate and sanitize data. Developers should be familiar with these functions and ideas
http://codex.wordpress.org/Data_Validation
WPDAY BOLOGNA - SEPTEMBER, 13 2013
VALIDATING: CHECKING USER INPUT
To validate is to ensure the data you’ve requested of the user matches what they’ve submitted.
There are several core methods you can use for input validation; usage obviously depends on the type of fields you’d like to validate.
http://codex.wordpress.org/Data_Validation#Input_Validation
Let’s take a look at an example.
<input id="my-zipcode" type="text" maxlength="5" name="my-zipcode" />
We’ve limited the input to five characters of input, but there’s no limitation on what they can input. They could enter “11221″ or “eval(“. Or even more characters if they change the HTML.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
VALIDATING: CHECKING USER INPUT
1 $safe_zipcode = intval( $_POST['my-‐zipcode'] );
2 if ( ! $safe_zipcode )
3 $safe_zipcode = '';
4 update_post_meta( $post-‐>ID, 'my_zipcode', $safe_zipcode );
The intval() function casts user input as an integer, and defaults to zero if the input was a non-numeric value.
We then check to see if the value ended up as zero. If it did, we’ll save an empty value to the database. Otherwise, we’ll save the properly validated zipcode.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
SANITIZING: CLEANING USER INPUT
Whereas validation is concerned with making sure data is valid – data sanitization is about making it safe. Even ‘valid’ data might be unsafe in certain contexts.
You cannot ask “How do I make this data safe?”. Instead you should ask, “How do I make this data safe for using it in X”.
<input id="title" type="text" name="title" />
Tex$title = sanitize_text_field( $_POST['title'] );2
update_post_meta( $post-‐>ID, 'title', $title );t
We could sanitize the data with the sanitize_text_field() function:
WPDAY BOLOGNA - SEPTEMBER, 13 2013
SANITIZING: CLEANING USER INPUT
Behinds the scenes, the function does the following:
•Checks for invalid UTF-8
•Converts single < characters to entity
• Strips all tags
•Remove line breaks, tabs and extra white space
• Strip octets
The sanitize_*() class of helper functions are super nice for us, as they ensure we’re ending up with safe data and require minimal effort on our part.
WPDAY BOLOGNA - SEPTEMBER, 13 2013
ESCAPING: SECURING OUTPUT
For security on the other end of the spectrum, we have escaping. To escape is to take the data you may already have and help secure it prior to rendering it for the end user.
WordPress thankfully has a few helper functions we can use for most of what we’ll commonly need to do:
esc_html() we should use anytime our HTML element encloses a section of data we’re outputting.
</pre><h4><!-‐-‐?php echo esc_html( $title ); ?-‐-‐></h4><pre>
esc_url() should be used on all URLs, including those in the ‘src’ and ‘href’ attributes of an HTML element.
<img alt="" src="<?php echo esc_url( $great_user_picture_url ); ?>" />
WPDAY BOLOGNA - SEPTEMBER, 13 2013
ESCAPING: SECURING OUTPUT
esc_js() is intended for inline JavaScript.
var value = '<?php echo esc_js( $value ); ?>';
esc_attr() can be used on everything else that’s printed into an HTML element’s attribute.
<ul class="<?php echo esc_attr( $stored_class ); ?>">
It’s important to note that most WordPress functions properly prepare the data for output, and you don’t need to escape again.
<h4><?php the_title(); ?></h4>
WPDAY BOLOGNA - SEPTEMBER, 13 2013
Danilo ErcoliAutomattic Inc.
http://daniloercoli.com
RELATORE
Danilo ha più di 10 anni di esperienza nello sviluppo di soluzioni software per il web e per il mobile. Ha lavorato con i più disparati linguaggi di programmazione, dall’assembler a SmallTalk, dal C all’ Object-C passando per Lisp, Java e PHP. Sviluppatore certificato PHP e Java2 SE. Molto tempo fa ha anche scritto un compilatore per il linguaggio Tiger. Attualmente lavora in WordPress.com passando gran parte del tempo sviluppando le soluzioni mobili offerte da WordPress e sviluppando componenti server a supporto del mobile. Lead Developer di WordPress for BlackBerry and PlayBook.
BIO
WPDAY BOLOGNA - SEPTEMBER, 13 2013