Skip to content

Instantly share code, notes, and snippets.

@9034725985
Forked from adrian-enspired/php-first.md
Created February 29, 2016 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 9034725985/dcd1c6b6930fc9a56941 to your computer and use it in GitHub Desktop.
Save 9034725985/dcd1c6b6930fc9a56941 to your computer and use it in GitHub Desktop.
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.

<?php
$page["id"] = 1;
$page["title"] = "Hello, World!";
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title><?= $page["title"] ?></title>
</head>
<body>
<?php
session_start();
if( isset( $_SESSION["user"] ) ){
echo '<p class="welcome">Welcome, '.$_SESSION["user"].'!';
}
else{
echo '<p class="welcome">Welcome, Guest!</p>';
echo '<a href="/login.php">Click Here to log in</a>';
}
?>
<h1><?= $page["title"] ?></h1>
<?php
$DB = new PDO( … );
$stmt = $DB->prepare( "SELECT heading,body FROM content WHERE page=:page" );
$stmt->execute( ["page"=>$page["id"]] );
while( $row = $stmt->fetch() ){
echo "<h2>".htmlspecialchars( $row["heading"],ENT_QUOTES,"UTF-8" )."</h2>";
echo "<p>".htmlspecialchars( $row["body"],ENT_QUOTES,"UTF-8" );
}
?>
</body>
</html>

As you might have guessed, this won't even work. For example, you'd say, "everyone knows session_start() has to be at the top of your script!!" (ahh, but why?)

But there are probably more problems than you think. What happens if there's an error connection to the database?

"Hello, World! Fatal Error: uncaught PDOException with message 'here's my DB password!' ..."?

You can't even show a nice error page, because you've already started printing this page.

<?php
session_start();
$page["id"] = 1;
$page["title"] = "Hello, World!";
$user = isset( $_SESSION["user"] )?
$_SESSION["user"]:
"Guest";
try{
$DB = new PDO( … );
$stmt = $DB->prepare( "SELECT heading,body FROM content WHERE page=:page" );
$stmt->execute( ["page"=>$page["id"]] );
while( $row = $stmt->fetch() ){
$contents[] = [
htmlspecialchars( $row["heading"],ENT_QUOTES,"UTF-8" ),
htmlspecialchars( $row["body"],ENT_QUOTES,"UTF-8" )
];
}
}
catch( PDOException $E ){
log_error( $E->getMessage() );
header( "Location: http://example.com/error-message.html" );
exit;
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title><?= $page["title"] ?></title>
</head>
<body>
<p class="welcome">Welcome, <?= $user ?>!
<?php if( $user === "Guest" ): ?>
<p><a href="/login.php">Click Here to log in</a>
<?php endif; ?>
<h1><?= $page["title"] ?></h1>
<?php foreach( $contents as list( $heading,$body ) ): ?>
<h2><?= $heading ?></h2>
<p><?= $body ?>
<?php endforeach; ?>
</body>
</html>

Just a little bit of reorganization, and all the problems are gone. See how there's a clear, dividing line that separates your "behind-the-scenes" work on the server from the body of your response?

"php FIRST" is really the least you should be doing; but it is a big, positive step. If you do this and nothing more, my rage will be quieted. However, it's a solid foundation for learning about:

  • templating
  • separation of concerns

have fun!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment