Skip to content

Instantly share code, notes, and snippets.

View adrian-enspired's full-sized avatar

Adrian adrian-enspired

View GitHub Profile

OK, so you have a filepath made from user input; something like

$path = __DIR__ . "/uploads/{$user_input_filename}"

#1: DO NOT DO THIS. Make up your own directory names. The user has no business picking path names on your server.

#2: Filesystem traversal is bad. If you mean for the given $user_input_filename to be inside the __DIR__ . "/uploads/ directory, take a moment to check.

@adrian-enspired
adrian-enspired / array_extend_recursive.md
Last active October 13, 2021 21:48
array_merge|replace_recursive are frustrating.

say you have two arrays, $a1 and $a2, and you want to combine them.

<?php

$a1 = [
  'a' => 'foo',
  'b' => ['bar']
];
$a2 = [
  'a' => 'bar',
@adrian-enspired
adrian-enspired / bad-config.md
Last active November 27, 2021 05:04
magic configs are bad, mmmkay?

Here's a very common pattern. People recommend it everywhere. Put your config into a separate file, and require it in your script. Awesome, right!?

Halfway. Yes, doing it is better than not. BUT now you have a bunch of invisible variables in your script! This makes for code that is hard to read and debug, and is fragile because code that directly affects your script is far away from it.

Imagine you got a warning like "undefined index 'foo' …" one day. It seems obvious now — the config file is messed up. But what if there were a ton of other stuff going on around this? What if this happens six months later (when you've completely forgotten about where $config comes from)? Even worse, what if a second config file gets included somewhere in the same scope and these invisible variables start colliding!?

BAD.config.php

<?php
$config["foo"] = "Hello, World!";
@adrian-enspired
adrian-enspired / PDO_MySQL.prepare.php
Last active October 23, 2020 01:38
how to make a simple prepared statement for MySQL with PDO
<?php
// let's make a query.
// only sql. NO DATA! put a named parameter where the data would normally go.
// parameters start with a ":", contain letters, numbers, and underscores only, and are not quoted.
const SQL_SELECT = 'SELECT foo, bar, baz FROM myTable WHERE quxx = :quxx';
// that's the parameter marker ---^
// prepare the statement.
$selectStmt = $pdo->prepare(SQL_SELECT);
@adrian-enspired
adrian-enspired / PDO_mysql.connect.php
Last active November 17, 2021 03:16
how to make a new mysql connection with PDO.
<?php
$host = "db hostname";
$dbname = "db name";
$user = "db username";
$pass = "db password";
$charset = "UTF8MB4"; // if your db does not use CHARSET=UTF8MB4, you should probably be fixing that
$dsn = "mysql:host={$host};dbname={$dbname};charset={$charset}";
@adrian-enspired
adrian-enspired / print_r_lies.php
Last active November 28, 2018 02:37
print_r() is not helpful (in most cases, but especially for debugging) as it hides useful information from you. observe:
<?php
$a = [
"true",
true,
1,
"1",
"false",
false,
0,
@adrian-enspired
adrian-enspired / render_template.php
Last active March 13, 2020 02:28
template rendering function. this is meant to help explain how templates can work; it is not intended (and probably not suitable) to be used "as-is" in a production project.
<?php
/**
* loads a template with user-supplied variables and returns its output.
*
* @todo add validation and error handling to taste
*
* @param string $template filesystem path to the template to use
* @param array $with map of variables to provide to template
* @return string the template's output
@adrian-enspired
adrian-enspired / whitelist-1.php
Last active March 23, 2021 21:30
a "whitelist" is a list of acceptable values which you can compare an unknown value to, in order to be sure it is valid.
<?php
// basic concept:
$whitelist = [
'foo',
'bar'
];
if (in_array($unknown_value, $whitelist, true)) {
@adrian-enspired
adrian-enspired / php-first.md
Last active October 23, 2020 01:35
PHP _first_!

PHP First

Generally speaking, your PHP code can be sorted into two categories:

  • code which does work (processing input, controller logic, database access, error handling, etc.), and
  • code which produces output (echo, <?= $var ?>, plain <html>, etc.).

work goes FIRST. output goes LAST.


@adrian-enspired
adrian-enspired / post-defaults-concept.php
Last active January 1, 2021 03:13
I don't actually recommend this approach anymore. you're better off with a more holistic approach to input validation.
<?php
// I first saw this on freenode/##php, from Viper-7.
// first, make an array with ALL of the field names you expect, and default values for each.
// keys are field names; values are field defaults.
$defaults = [
"field1" => "default value",
"field2" => "", // ← default is empty string
"field3" => null // ← no default value