Or more accurately… how to get around this limitation
Author: cguWFsbYmg8KUvYmdH3G
How to Re-Create a Nifty Netflix Animation in CSS
The design for Netflix’s browse page has remained pretty similar for a few years now. One mainstay component is the preview slider that allows users to scroll through content and hover on items to see a preview.
How to Handle PHP Templating Without a Framework
PHP templating often gets a bad rap for facilitating subpar code — but that doesn’t have to be the case…
What’s the Difference Between Primitive Values and Object References in JavaScript?
A critical distinction between immutable and mutable data…
The Dangers of the ‘+’ Operator in JavaScript
How simple addition can misfire and break JavaScript applications in ways you might not expect…
How to Deploy Node.js Shopify Apps to Digital Ocean
A comprehensive guide to deploying your Node.js Shopify App to a production-grade Digital Ocean server…
How to Overcome Tough Bugs Without Pulling Your Hair Out
8 tips for breaking through roadblocks as a programmer…
Stop Putting So Many If Statements in Your JavaScript
4 other ways of handling conditional logic in your code…
JavaScript: Sets vs. Arrays
Introducing Sets, the ES6 data type you didn’t know you needed…
How To Make Your PHP Code Beautiful With Chainable Methods
PHP has a bad reputation for being ugly. The language evolved piecemeal over time, and it shows…
Some CSS Grid Strategies for Matching Design Mockups
The world of web development has always had a gap between the design process and the development process. Ambitious designers want the final result of their effort to look unique and beautiful (and true to their initial vision), whereas most developers find more value in an outcome that is consistent, dependable, and rock solid (and easy to code). This dynamic can result in sustained tension between the two sides with both parties looking to steer things their way.
While this situation is always unavoidable to some extent, new front end technology can play a role in bringing the two sides closer together. One such technology is CSS Grid – the remainder of this post will focus on how it can be used to write styles that match design layouts to a high degree of fidelity.
A common way that designers give instructions to front end developers is with design files. This could be done with Illustrator, Photoshop, XD, Sketch, etc. All designers work slightly differently, but many like to base the structure of their layouts on some kind of grid system. A 12 column is very common, but I’ve seen other patterns as well. This grid can be toggled on and off at the click of a button in many cases.

Once a grid system such as this is selected, most design elements should be positioned within it cleanly. This makes the shapes used on the page line up nicely and gives developers a distinct target to shoot for when writing CSS.
Unfortunately, this basic pattern can be deceptively difficult to code precisely. Tools like bootstrap that are often used to do this come with a list of problems for the front end perfectionist (such as the added page weight and lack of fine grain control). CSS grid offers a better solution – let’s look at an example.

The design above is a good application for grid. There is a 14 column pattern in place and multiple elements positioned within it. While the boxes all have different widths and offsets, they all adhere to the grid. This layout is possible to achieve with flexbox and even floats, but would likely involve a lot of math to get pixel perfect across all breakpoints, and many front end developers don’t have the patience for that. Let’s look at 3 CSS Grid layout strategies for doing this kind of work more easily.
A Basic Grid
The most intuitive way to write an evenly spaced 12 column layout would be some variation of this. Here, an outer container is used to control the side gutter spacing with left and right padding, and an inner row element is used to restrain content to a maximum width. The row also receives some grid specific styling:
display: grid; grid-template-columns: repeat(12, 1fr); grid-gap: 20px;
This rule defines the grid to consist of 12 columns, each having a width of 1 fractional unit (1fr). A gap of 20px between columns is also specified. With the column template set, the start and end of any child column can be set very simply using the grid-column property. For example, setting grid-column: 3/8; positions that element to begin at column 3 and span 5 units across to column 8.
We can already see a lot of value in what CSS Grid is providing, but this approach has some limitations. One problem is Internet Explorer, which doesn’t have support for the grid gap property. Another problem is that this 12 column approach does not provide the ability to start columns at the end of gaps or end columns at the start of gaps. For that, another system is needed.
A More Flexible Grid
Although grid gap may be a no go for IE11, the appearance of gaps can be recreated by including the spaces as part of the grid template itself. The repeat function available to grid-template-columns accepts not just single column width as an argument, but repeating patterns of arbitrary length. To this end, a pattern of column-then-gap can be repeated 11 times, and then the final column can be inserted to complete the 12 column/11 gap layout desired:
grid-template-columns: repeat(11, 1fr 20px) 1fr;
This gets around the IE11 restriction, and also allows for columns to be started and ended on both columns or gaps. While being a nice improvement over the previous method, it still has some room to grow. For example, what if a column was to be positioned to have one side span to the edge of the screen, and the other fit within the grid system. Here’s an example:

In this layout the left column appearing as the card starts and ends within the grid. The rightward image begins within the grid as well, but extends beyond the grid to the edge of the browser. Let’s look at a way to make this doable.
An Even More Flexible Grid
This technique builds on the idea introduced in the last revision. Instead of having the grid exist within other elements that define the gutter sizes and row widths, it integrates those spaces with the grid’s pattern itself.
$row-width: 1140px;
$gutter: 30px;
$gap: 20px;
$break: $row-width + 2 * $gutter;
$col-width-post-break: ($row-width - 11 * $gap) / 12;
.container {
display: grid;
grid-template-columns: $gutter repeat(11, calc((100% - 2 * #{$gutter} - 11 * #{$gap})/12) #{$gap}) calc((100% - 2 * #{$gutter} - 11 * #{$gap})/12) $gutter;
@media screen and (min-width: #{$break}) {
grid-template-columns: calc(0.5 * (100% - #{$row-width})) repeat(11, #{$col-width- post-break} #{$gap}) #{$col-width-post-break} calc(0.5 * (100% - #{$row-width}));
}
}
To get this just right, some math is required. It’s important to have the template set differently before and after the maximum width of the row has been reached. I elected to use Scss for this as defining variables can make the calculation a lot more manageable (not to mention readable for others). What started as a 12 part pattern grew to a 23 part pattern with the integration of the 11 interior gaps, and is now 25 pieces accounting for the left and right gutters.
One cool thing about this approach is that once the pattern is set it can be used as the basis for many different layouts throughout the project, including traditionally awkward layouts like the example above. Moreover, it serves as a straight forward way to precisely implement designs that are likely to be handed down from designer to developer.
Caveats
- This alignment system is most useful when the grid includes a known number of child elements that can have their position set explicitly with the
grid-columnproperty. Auto placement can cause problems because gutters and gaps are set as columns in the template. - CSS Grid behaves in a similar way to Flexbox in that columns with widths set to be fractional units will grow or shrink depending on their siblings and contents. In this demo all columns are empty of content and so they all grow at equal rates, but in production you may want to substitute
1frforminmax(0, 1fr)
How to Create Lightweight Parallax Effects
Great progress has been made in the general user experience of the web in recent years. In stark contrast to early popup animations that polluted webpages in the early days of HTML, designers have now caught on to the idea of creating “Natural” experiences. These experiences take inspiration from the physical world – a world where things don’t appear and disappear instantaneously, but instead fade in and fade out, or move in and out of a person’s sight smoothly. Another feature of the physical world is the existence of spatial depth – that is, things are 3D and not 2D as they appear on a computer screen.
While virtual reality is working on overcoming this obstacle, 2D surfaces like webpages can use some tricks to make things seem to have depth. On such trick is “Parallax”, a technique in which different components of a page scroll at varying relative speeds. This method makes it seem as though multiple layers exist on a simple plane, and make things seem more lifelike to users. The added attraction of parallax makes it a great way to grab a user’s attention at the top of a page.
Parallax is most often established by a combination of CSS and JS, and several libraries are available to achieve this effect more easily. The objective of this post, however, is to show how this can be done more minimally.
This codepen marks our starting point. A captivating image has been selected with a bold headline in an attempt to maintain the attention of the user, but parallax could improve it further.
This makes for a good start. One important detail to notice is that a distinct element (hero__backgroundImage) has been created for the background image, and this element has been absolutely positioned within its container. This separation is important because it allows the image to move independently of its container.
With the basic markup in place, the next step is considering how the relative motion is best created. One idea would be setting the background position of the image to vary with the window’s scroll position. A pure JS implementation of this strategy is shown in the following pen. Notice that the browser’s requestAnimationFrame API is used to throttle CSS property writes to a reasonable frequency. Fortunately, this method now has great cross browser support: https://caniuse.com/#feat=requestanimationframe.
While this technique gets the job done nominally, it breaks some performance best practises. Namely, it relies on animating the background-position-y property, which is not ideal. It’s well known that transform and opacity make the best targets for animation if performance is of importance. With this in mind the final solution can be improved to the following (Interestingly, the smoothness of these variations are not noticeable to myself. Perhaps they would be more apparent on more complex sites running on slower computers).
How to Deploy Node.js Projects
Node.js has become increasingly prevalent in web application technology stacks in the recent years. Corporate giants like Netflix and Linkedin are now using it to drive a significant portion of their business logic, and the developer community has embraced the new technology with open arms. In addition to revamping the workflow of modern front end applications, Node.js is now moving in on the market share of more established server side scripting languages such as PHP, Python, and Ruby.
With a promising future ahead, various stakeholders of the web want to learn more about how Node.js works. Business’ want to see what advantages it could give them over their competition, experienced developers want to futureproof their skillset, and new developers want to learn a technology that is enjoyable, employable, and approachable.
The new ability to run Javascript server side grants organizations the opportunity to limit their applications to one single programming language and makes the title of “Fullstack Developer” more accessible to programmers that have thus far worked exclusively on client facing work. The considerable investment that Google has made on its V8 Javascript engine is taken full advantage of with Node.js, which stacks up well with other scripting languages in metrics of speed and performance.
With all these factors in play, how do you actually get your hands dirty and deploy a Node.js app to the web? Despite being largely beginner friendly, deploying serverside Javascript can be tricky, especially if you have requirements similar to mine – here’s the list:
- Since these are personal projects, they shouldn’t be expensive (ideally cheap or free).
- The project should be easily deployable based on a remote git repository.
- This git repository should be publicly viewable (so others can see your work) but should not compromise security (no leaked credentials).
- Although the app isn’t expected to get much traffic, it should still be fast to the visitors that it gets.
- The app should be served over https and use a custom domain name.
- Adding additional apps to the platform should be simple and inexpensive.
These six requirements are ambitious but attainable. This posts explores how these objectives can be met in part with Heroku and in full with Digital Ocean.
Heroku
There is a lot to like about Heroku as a developer. The platform offers a robust command line tool that allows you to manage your Node app from a local terminal window (although many things can also be achieved through their web based UI), manages the bulk of the dev ops tasks for you, features an extensive list of add ons (services like a MySQL or MongoDB database, for example), and provides comprehensive documentation. In it’s basic form, deploying Node to Heroku is fairly easy (Full details can be read at https://devcenter.heroku.com/articles/deploying-nodejs.):
- Develop your app locally
- Version control you app with git and commit the code that you want to be deployed.
- Download Heroku’s command line tool and run
heroku createfrom the root of your project - Create an npm script that starts your app (eg
node app.js) in your package.json - Declare your preferred version of Node.js (a sensible choice may be your local version)
- Push to Heroku’s remote repository (eg
git push heroku master). You should now see a series of deployment commands execute and a live url if everything went smoothly.
At this point, you have a basic node process running, but you will likely need to have a database available as well. You have a few options here:
- The most straight forward option is to use an appropriate Heroku add on (eg MongoDB, https://elements.heroku.com/addons/mongolab). This can be done with the heroku cli (
heroku addons:create mongolab:sandbox). Heroku offers a free platform up to this point, but often requires a credit card for addons. - If you prefer, you may set your database to run external to Heroku. In the case of MongoDB. you could create a service directly with MLab (https://mlab.com/), for example.
Notice that a remote database is required for both of these options. Since the app cannot simply access its data over localhost (because they are running on different computers) credentials are required, and these need to be managed in a secure way.
The most natural way to handle this with Heroku is through environmental variables. Environmental variables can be created and updated by command line or web interface:

These config vars should not be exposed in a git repository (It’s bad practise to store credentials in a private git repo, and a flat out security vulnerability to store them in a public git repo). Thankfully, Node.js features a native API that allows it to read the environmental variables of its current process. Here’s a basic example:
const dbUrl = process.env.DB_URL || 'mongodb://localhost:27017/my-app' mongoose.connect(dbUrl)
On the first line, Javascript will check the value of DB_URL. If it finds it to be truthy, that value will be assigned to dbUrl. If it is not found to be truthy, then the local url (‘mongodb://localhost:27017/my-app’) is assigned instead (Note that this use of the || operator is somewhat Javascript specific and doesn’t extend to PHP, for example). This pattern is compatible with both the local and production environment, and keeps credentials secret.
With the problem of database connections solved, a fully functional Node.js app is now running on a public facing url! Further changes can be made by simply pushing subsequent commits to the Heroku remote repo, and additional services can be added to the app as needed.
Issues
Unfortunately, Heroku is not able to simultaneously meet all six requirements initially outlined. Although it offers a free tier to get started with, this basic plan only allows for a finite amount of monthly run time for you applications. The practical implication of this limit is that Heroku applications running on the free tier will “spin down” after a certain period of inactivity and then “spin up” again when a request is made, which often makes for very slow responses (~ 5s + in my experience). A load time of this length is so slow that a significant portion of would be users will simply bounce.
In addition to this primary performance issue, the inability to put a Node.js process on the same server as its pairing database introduces unnecessary network latencies and further hinders app performance (albeit to a much less extent).
Digital Ocean
Digital Ocean (DO) also offers application hosting, but provides a platform very different than Heroku. Unlike Heroku, DO allows you to do whatever you want with the server, and gives you this freedom at a lower price. Although this sounds nonintuitive at first, it’s important to acknowledge that this is also a liability. Although DO offers an assortment of “1 click” installation packages, you ultimately become responsible for the Dev Ops of your own VPS (Virtual Private Server) which is often tedious, error prone, and confusing for new developers.
That being said, DO can be configured to serve as a perfect hobby server to host personal projects of various tech stacks on a single VPS. There are many ways to do this, but this post shows how to create a Ubuntu Nginx/Apache server that serves Node.js applications on virtual hosts.
Getting Started
DO supplies Droplets as their basic unit of computation. A Droplet is essentially a virtual computer that serves as a workspace for whatever you wish. Once you signup for DO you can create a Droplet, specifying the operating system, computation power, etc. For the purpose of prototyping Node.js projects, a 1GB CPU (the most basic option) running Ubuntu is sufficient. This option costs 5USD/month currently. Virtually hosting can be leveraged to deploy all of our applications to this single droplet.
Once you’ve selected your options and spun up the virtual machine, you will be given SSH access. From this point forward all the configuration for the server is done via CLI. Fortunately, DO provides comprehensive documentation that makes our setup much easier. This can be handled one step at a time:
-
- The preliminary step is connecting to your VPS as root via SSH. This is straight forward on Mac and Linux, but if you are on Windows you may need to use a tool like Putty. DO gives help with this step here: https://www.digitalocean.com/docs/droplets/how-to/connect-with-ssh/
- Although logging in as root initially is unavoidable, it is considered good practise to create a new user to be used for most operations. This can be achieved by following this guide: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04.
- Once a non-root user is available to be used, Node.js can be installed. DO recommends PM2 here as a means of running the app. While it is possible to temporarily run a server directly (eg
node app.js), DO suggests PM2 as a means to run the app as a service. This allows you to logout of your droplet without stopping the app, and sets the app to restart after a fatal (500) error occurs. More information can be found at: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04 - (Optional) Following the steps of the link provided above will yield Node.js app being publicly exposed through an Nginx reverse proxy. Although Nginx outperforms Apache for serving websites to many users simultaneously, this isn’t a critical consideration for a hobby server and I’m partial to Apache. If you want to run Apache as a web server instead of Nginx, these links might be handy to you – https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-ubuntu-16-04, https://stackoverflow.com/questions/14369865/running-node-js-in-apache
- Both Nginx and Apache traffic can be better secured by forcing all traffic to work on https. Let’s Encrypt serves as a way to do this for free: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04, https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04
- Unlike Heroku, DO grants us the flexibility of running our database management system from the same host as the Node.js server. As a single example, this article explains how to properly run MongoDB: https://www.digitalocean.com/community/tutorials/how-to-install-mongodb-on-ubuntu-16-04. Avoiding the network latencies inherit to remote database connections often come with noticeable speed improvements.
The server configuration process is now essentially complete and your app should be running soundly on a virtual host. With the exception of the points related to git, all the requirements have been met.
Digital Ocean Version Control & Deployment
Git can be used as a key tool for deployment, and a workflow similar to that of Heroku’s can be achieved by automating this process.
- First, prepare a remote repository for your projects code (eg Github or Bitbucket) and push your latest changes to that location.
- Install git on your droplet: https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-16-04. Once git becomes available, clone the project to its appropriate directory.
- The project can now be updated by simply pulling recent changes from the remote repository to the VPS. However, the process of connecting to a server by SSH, navigating to the appropriate directory, pulling changes, and possibly running a build script or package installer is tedious. This can be automated by creating a bash file – here’s an example:
#!/bin/bash ssh 138.33.33.333 << 'ENDSSH' cd my-project git checkout . git pull origin master npm install ENDSSH
This script can be triggered by running
./deployfrom the command line of your local machine (make sure it has appropriate permissions for executing). Deployment is now automated – this process will login to the droplet, find the appropriate folder, clear any local changes, pull new changes from the remote repository, and ensure that all tracked packages are installed. A build process may also be executed here (egnpm run build), which would permit generated files to be ignored from version control.
Managing Credentials
Credential management is left more open ended in DO than Heroku. One solution is using a package like dotenv (https://www.npmjs.com/package/dotenv) that allows for environmental variables to be defined in a separate file. A more minimal solution (which I prefer) is creating a conf.js file at the root of your project folder and excluding it from version control. It could look like this:
module.exports = {
dbUrl: 'mongodb://localhost:27017/my-app',
secret: 'Tony Hawk'
}
Including an example file (eg conf.example.js) in version control is a good idea. It serves as a reminder to yourself and allows other people to get a project running without thinking too hard. Once this is in play you can modify the app’s connection line as follows to make it compatible with local, Heroku, and DO environments.
const dbUrl = process.env.DB_URL || require('./config').dbUrl
mongoose.connect(dbUrl)
Conclusion
Heroku and Digital Ocean are two of the most common ways to host Node.js applications. Although many budget hosting providers do not provide the server side V8 runtime, Digital Ocean can be configured to run any number of apps on a single $5/month droplet that is easily deployable, secure, and reliable for modest load sizes. Heroku offers a sleek toolkit and solid hosting, but these feature will cost you – especially if you want to have several instances running simultaneously.
PHP Debugging: Pitfalls and Solutions
Web development is a challenging endeavour, and this challenge is only increasing as the web matures. What might have been considered a passable website ten years ago would seem starkly outdated to the user of today, and modern businesses are diverting more and more resources towards their online presence.
The complexity of both front-end and back-end web development has risen to meet these standards, and the software writers of today are responsible for managing this complexity. And although various frameworks and tools have emerged to make this process easier, much of this cognitive load still falls squarely on developers.
Building features that meet requirements and work without bugs isn’t easy, and as such programs need to be iteratively debugged before deployment. Debugging is absolutely critical here, and often consumes much more time than developers like to admit. For these reasons, approaching the act of debugging strategically can have a remarkable impact on programmer productivity.
As a modern developer who is involved in several layers of the application stack, it’s interesting to observe that not all of these layers are equally easy to debug. The refinement of in-browser development tools (with a prime example being Chrome’s dev tools) has played a key role in making the client side components of an application debuggable.
The DOM itself can be inspected elegantly, CSS styles can be monitored and tweaked in real time, and breakpoints can be inserted into client running scripts without trouble. Popular Javascript libraries such as React and Vue offer browser extensions perfectly tailored to the infrastructure of their framework. The Javascript console itself is attractive, feature rich, and an indispensable resource to developers.

All of this is to say that debugging can be done fairly well on the client side of a web application. But of course, this isn’t the full picture. The behaviour of server side services such as your web server, database management system, and programming language are more than likely going to require debugging at some point as well.
Naming names, PHP scripts are especially frustrating to debug. With many of the features of the browser’s developer tools unavailable, identifying and fixing bugs can be tedious at best. The remainder of this post focuses on some of the various tools and strategies available for this task.
The Example
To compare the pros and cons of these strategies in a concrete way, let’s look at an example. In this use case, our script has access to an array that contains information about various students who attend Springfield Elementary:
$students = [
[
'name' => 'Millhouse',
'grade' => 60,
],
[
'name' => 'Lisa',
'grade' => 95,
],
[
'name' => 'Bart',
'grade' => 35,
],
];
Consider a scenario in which it becomes desirable to filter this list of students based on their grade. One way to achieve this would be by using PHP’s built in array_filter function:
$grade_threshold = 50;
$passing_students = array_filter($students, function($student) {
return $student['grade'] >= $grade_threshold;
});
?>
<h3>Passing Students</h3>
<ul>
<?php foreach ($passing_students as $student): ?>
<li>
<?= $student['name'] ?> - <?= $student['grade'] ?>%
</li>
<?php endforeach; ?>
</ul>
However, this script does not perform as expected. A notice titled Undefined variable: grade_threshold is generated on each iteration, and Bart (who has a grade of 35) appears in the outputted list. Clearly, something is wrong here.
Classic Debugging
The most basic way to debug PHP is by simply printing values that you suspect to be working incorrectly. Built in functions such as echo, print_r, and var_dump can be used to do this.
echois designed to print text (either plain or HTML) and will convert all values to strings. This coercion often results in values being outputted in unexpected ways (for example, values of null and false appear as an empty string, and an array with appear as the literal string “Array”).print_ris essentially a recursiveecho. Although this function allows for arrays and objects to be visualized, it still fails to communicate types.var_dumpworks likeprint_rbut also contains information about the value’s type. For this reason,var_dumpis often a better tool for debugging thanechoorprint_r.
Applying this knowledge to our example, one might elect to execute a var_dump on the $grade_threshold from within the array_filter callback, and then execute another var_dump on $passing_students once the filtering has completed:
$passing_students = array_filter($students, function($student) {
var_dump($grade_threshold);
return $student['grade'] >= $grade_threshold;
});
var_dump($passing_students);

Based on the output above, it’s clear that the $grade_threshold variable does not exist within the loop, and that Bart is indeed passing the filter test. At this point a PHP dev might recall that callback functions do not have access to external variables (unlike Javascript or Python). This can be fixed by explicitly granting the callback access to the variable via the use keyword:
$passing_students = array_filter($students, function($student) use ($grade_threshold) {
return $student['grade'] >= $grade_threshold;
});
Once this change is made, Bart will be stop appearing in our output and our script will perform correctly. Bug fixed!
In this situation, classic debugging techniques are sufficient to find our bug, but real world codebases often present additional roadblocks. For starters, unformatted print_r and var_dumps of large arrays and objects are ugly and hard to read, so debug data is often wrapped in pre tags to clean things up a bit. Utility functions that “dump and die” can be written to handle this:
function dd($data) {
echo '<pre>';
var_dump($data);
echo '</pre>';
die();
}

But even after writing a dedicated debugging function, things often continue to be messy. Web applications typically involve several stylesheets and scripts designed to produce a specific layout, and that layout may not be visually compatible with your debugging data. Unfortunately, the front end output and development debugging info are now competing for the same real estate (your browser window), and this is a major problem with classic PHP debugging.
Clever Workarounds
As mentioned earlier, the javascript console can be used to display data in a structured and inspectable form. Although some PHP data types (such as associative arrays) cannot be converted to Javascript, it is possible to encode data in JSON form and send it to the javascript console to be presented:
function console_log($data) {
?>
<script>
console.log(<?= json_encode($data) ?>)
</script>
<?php
}
But although this solution solves many of the formatting challenges outlined above, it can also create confusion. Once again, PHP errors are being sent to display in a location that is normally reserved for a different purpose.
Error Logs
PHP can be configured to log errors to a server side file, and most production servers elect for this approach for the purpose of security and professionalism. It’s also possible to write directly to this file by way of the built in error_log function. This technique finally moves our debugging data off the client, but suffers from the same shortcomings in formatting and modularity as previous methods.
Xdebug
PHP can be debugged more easily with the help of Xdebug (https://xdebug.org). Upon installation, error messages and var_dumps are immediately improved:

Step by step debugging with break points also becomes possible with Xdebug, and VS Code offers a great free extension called PHP Debug (https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) that integrates with this seamlessly. Once configured, Xdebug runs locally on an independent port (Port 9000 by default), and VS Code can be triggered to listen to its output and pause at preset breakpoints (much like what Chrome dev tools offers for Javascript)

This solution finally provides a dedicated window for tracking variables and error/warning messages. The program’s execution can be paused and resumed at will, and breakpoints can be added and revised with ease. No lines of code need to be added to the script for the purpose of debugging, and nested values like arrays and objects can be collapsed and expanded.
Coming back to our example, adding a breakpoint inside the callback function allows for us to see the $grade_threshold variable as apparently uninitialized, which grants insight on the underlying scope problem causing the bug. All in all, Xdebug coupled with VS Code offers a level of professionalism and polish lacking in classic debug methods.
Installation and Setup
Xdebug works especially easily with MAMP PRO (my platform of choice for most PHP projects). In this case, the extension comes preinstalled and turning it on is as easy as clicking a checkbox and restarting the server. Installation of the VS Code package was similarly easy in my case.

Although things largely worked out of the box, I found that I had to adjust my php.ini file to ensure that large nested arrays and objects were fully available from VS Code’s variables panel.

You might not need Javascript for that: Filtering
Making collections of items filterable is a common way to make data more accessible to users on the web. Many ecommerce platforms allow for products to be searched, then filtered by specifications such as price, brand, rating, etc. This allows customers to find the products that they want quickly which ultimately boosts sales.
Filtering functionality can be developed using several techniques:
Server side via query strings
One classic way of building filter functionality is by setting the filter categories to be anchor tags that contain query strings. When the user clicks on a filter, the page is re-requested with new url parameters (eg /products?min-rating=4). The server then reads the parameter and responds with items matching the given filter. This strategy is solid and dependable, but requires an additional page reload which is beginning to feel dated. As a real world example, WordPress’s ubiquitous Woocommerce plugin uses this technique for product categories.
Javascript
Javascript filters have become more and more popular, and can be implemented in a few different ways. Javascript filters can be built by either sending all the data initially and storing it (in Javascript as a variable, in the DOM, etc), or by sending additional requests for data to the server via AJAX. The former technique can be workable for small amounts of data, but is inappropriate for large amounts of data. For example, Amazon wouldn’t send all the data for a product search up front because there is just too much of it.
The mechanics of changing data can be handled in different ways as well. Javascript libraries that allow state to be managed easily like React, Vue, and Angular make these operations simple. On the other hand, doing this with jQuery (or without any framework), while certainly manageable, is more difficult because the developer needs to add and remove appropriate items from the DOM manually.
CSS
You may not of thought it possible, but CSS actually has the firepower to emulate this behaviour as well. The rest of this post is dedicated to showing how. Here’s the demo:
In this example, I’m grabbing some base styles from Bootstrap and extending them with SCSS. Here’s the key details that make this work:
A radio input is created for each category. By using a common name attribute, these inputs are grouped and only one can be active at a time.
Bootstrap’s tab components are used to display each filter category. Instead of containing an anchor tag, each tab contains a label.
Each label is linked to an associated radio input by setting its for attribute to an input id. Now when a label is clicked, its input will become active.
The ~ selector can be used to select sibling elements that appear after another. When combined with the :checked selector, it becomes possible to target a given element (the labels and the grid item itself) when a radio button is selected.
Since the labels are being used as buttons and we don’t want to display the radio buttons, those are hidden via display: none; (but they are still being toggled when labels are clicked)
By setting the input id attribute, label for attribute, and item class consistently, styling can be automated via a scss @each loop.
A basic animation can be setup so that items fade in when they go from hidden to shown.
That the just of it. Although this technique is totally unsuitable for complex situations and is probably more complicated than a Javascript solution, its cool to see that this can be done without it.
SQL Injection: A Concrete Example of What NOT to Do
SQL Injection is one of the most common ways to attack a website. Using this method, hackers enter text containing SQL code into form inputs, hoping that the server’s code is poorly designed and susceptible to their trick. The purpose of this post is to show a specific example of how these kind of attacks could find success, and also how to guard against it.
The context for this example is an HTML Subscription Form. When the user submits their email and name, a post request will be sent to the server and a PHP script will attempt to enter this information into a MySQL database.
It’s worth noting that the possibility of SQL injection problems go down considerably if your project is built on a reputable framework (eg Laravel, Rails, Django, etc) and you stick to using the ORM. In this case, you may be able to avoid writing SQL queries all together.
In this example, I’ll be using PHP and it’s PDO class to connect to MySQL and write to it. Although PHP offers other APIs capable of doing the same thing, PDO comes with the advantage of being DBMS agnostic (ie it works with not only MySQL, but also Postgres, Oracle, etc), which could be handy if you want to change your project’s infrastructure down the road.
Now, onto the code. Here’s the form’s HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Subscribe!</title>
</head>
<body>
<h1>Subscribe to our newsletter!</h1>
<form action="subscribe.php" method="POST">
<input name="email" type="email" placeholder="email" required>
<input name="name" type="text" placeholder="name" required>
<input type="submit" value="Submit">
</form>
</body>
</html>
And here’s the first attempt at the PHP controller responsible for interfacing with our database:
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "root";
$db = "test";
$table = "users";
try {
$conn = new PDO("mysql:host=$servername;dbname={$db};", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE TABLE IF NOT EXISTS {$table} (email varchar(255), name varchar(255));";
$conn->exec($sql);
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
$email = $_POST['email'];
$name = $_POST['name'];
$sql = "INSERT INTO {$table} (email, name) VALUES ('{$email}', '{$name}');";
$conn->query($sql);
echo "<h3>hi, {$name}! Thanks for subscribing!</h3>";
Translated to english, subscribe.php is:
- Connecting to the database
- Creating a users table if one does not already exist
- Saving our form input into variables
- Using these variables to create an SQL statement intended to insert these values into a new row.
- Executing the SQL statement
- Providing confirmation to the user
This script will in fact work most of the time. So long as the user does not come with malicious intent and enters real emails and names into the form, all is well. However, assuming that all your users will come with good intent is a mistake!
In this attempt, user input is being put between quotes so that SQL will take them as literal values (line 25), but what happens when the user inserts quotes of their own? In that case, the literal string terminates and any further text will be executed as SQL. This vulnerability allows the attacker to write whatever SQL statements they want and execute them on our database!
For example, what would happen if this was put into the name field?
'); DELETE FROM users; INSERT INTO users (email, name) VALUES ('hax@gmail.com', 'Ha! Gotcha!
Originally, our database may have some users, like so:

But after inserting the above text as a name:

Whoops! And deleting users is only one example of bad things that can be done with SQL injection. Even worse situations exist, where multiple databases could be dropped, or users could fool your site into logging them in as another user (potentially an admin user). This is bad news, so how can it be prevented?
One way to neutralize this threat is using the PDO class’s prepare and bindParameter methods, which will escape any quotes it sees and ensure that user input does not leak into a SQL statement. Here’s what that looks like:
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "root";
$db = "test";
$table = "users";
try {
$conn = new PDO("mysql:host=$servername;dbname={$db};", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE TABLE IF NOT EXISTS {$table} (email varchar(255), name varchar(255));";
$conn->exec($sql);
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
$email = $_POST['email'];
$name = $_POST['name'];
$sql = "INSERT INTO {$table} (email, name) VALUES (:email, :name);";
$statement = $conn->prepare($sql);
$statement->bindParam(':email', $email);
$statement->bindParam(':name', $name);
$statement->execute();
echo "<h3>hi, {$name}! Thanks for subscribing!</h3>";
Using this improved code in our subscribe controller will yield these results when injection is attempted:

Ha! This time the SQL code is entered as normal text, and our earlier entrees are preserved. Although this method of SQL execution is not necessary for all situations, it is a good way to deal with values that you can’t trust like user input. The code for this demo can also be seen at https://github.com/chris-geelhoed/sql-injection-example










