SlideShare a Scribd company logo
Coding
Horrors
A Horror Film Fan’s Guide to
PHP Coding Nightmares
Coding
Horrors
Coding Horrors
Coding Horrors – Friday the 13th
Coding Horrors – Friday the 13th
// 3 month appointments
$date_to = date('d/m/Y');
$date_from = date("d/m/Y", strtotime(" +3 months"));
$get = "select * from appointments where date between '$date_from' and '$date_to'";
$get_connect = mysqli_query($con2, $get);
$get_rows = mysqli_num_rows($get_connect);
Coding Horrors – Friday the 13th
mysql> select * from appointments;
+----+-----------+------------------------+
| id | date | appointment |
+----+-----------+------------------------+
| 1 | 2/1/2018 | PHPNW January meetup |
| 2 | 6/2/2018 | PHPNW February Meetup |
| 3 | 6/3/2018 | PHPNW March Meetup |
| 4 | 3/4/2018 | PHPNW April Meetup |
| 5 | 1/5/2018 | PHPNW May Meetup |
| 6 | 5/6/2018 | PHPNW June Meetup |
| 7 | 3/7/2018 | PHPNW July Meetup |
| 8 | 7/8/2018 | PHPNW August Meetup |
| 9 | 4/9/2018 | PHPNW September Meetup |
| 10 | 2/10/2018 | PHPNW October Meetup |
| 11 | 6/11/2018 | PHPNW November Meetup |
| 12 | 4/12/2018 | PHPNW December Meetup |
+----+-----------+------------------------+
12 rows in set (0.01 sec)
mysql> select * from appointments
-> where date between '2/1/2018' and '5/1/2018’;
+----+-----------+------------------------+
| id | date | appointment |
+----+-----------+------------------------+
| 1 | 2/1/2018 | PHPNW January meetup |
| 4 | 3/4/2018 | PHPNW April Meetup |
| 7 | 3/7/2018 | PHPNW July Meetup |
| 9 | 4/9/2018 | PHPNW September Meetup |
| 10 | 2/10/2018 | PHPNW October Meetup |
| 12 | 4/12/2018 | PHPNW December Meetup |
+----+-----------+------------------------+
6 rows in set (0.00 sec)
Coding Horrors
Coding Horrors – The Ring
Coding Horrors – The Ring
$studentArray = array();
$query1 = "SELECT * FROM students ORDER BY name";
$studentList = mysqli_query($conn,$query1)
or die ("cannot query the table1: " . mysqli_error($conn));
while ($student = mysqli_fetch_array($studentList)) {
$studentId = $student['id'];
$courses = array();
$query2 = "SELECT * FROM classes WHERE studentid='$studentId'";
$classList = mysqli_query($conn,$query2)
or die ("cannot query the table2: " . mysqli_error($conn));
while ($class = mysqli_fetch_array($classList)) {
array_push($classes, $class['name']);
}
array_push($studentArray, array($studentId, $student['name'], implode(', ', $classes)));
}
Coding Horrors – The Ring
SELECT s.id,
s.name,
group_concat(c.name separator ', ')
FROM students s
LEFT JOIN classes c
ON c.studentid = s.id
GROUP BY s.id,
s.name
ORDER BY s.name;
Coding Horrors – The Ring
SELECT s.id,
s.name,
c.name
FROM students s
LEFT JOIN classes c
ON c.studentid = s.id
GROUP BY s.id,
s.name
ORDER BY s.name;
Coding Horrors
Coding Horrors – The Mummy
Coding Horrors – The Mummy
$Data = $connection->prepare(
"SELECT * FROM :TableName ORDER BY :OrderByColumn :OrderDirection LIMIT 10 OFFSET :Offset"
);
$Data->bindValue(':TableName', $TableName, PDO::PARAM_STR);
$Data->bindValue(':Offset', $Offset, PDO::PARAM_INT);
$Data->bindValue(':OrderByColumn', $OrderColumn, PDO::PARAM_STR);
$Data->bindValue(':OrderDirection', $OrderDirection, PDO::PARAM_STR);
$Data->execute();
Coding Horrors
Coding Horrors – Night of the
Living Dead
Coding Horrors – Night of the
Living Dead
function getAddressDetails() {
$data->name = 'Mark';
// $data->address = 'mi casa';
// $data->city = 'Manchester';
// $data->country = 'UK';
// return json_encode($data, JSON_UNESCAPED_UNICODE);
return json_encode($data);
}
Coding Horrors – Night of the
Living Dead
function getAddressDetails() {
$data->name = 'Mark’;
return json_encode($data);
}
git commit -m "Remove address, which is now accessed through a separate API call"
Coding Horrors – Night of the
Living Dead
function addValues($a, $b, $options) {
$sum = 0;
return $a + $b;
}
Coding Horrors – Night of the
Living Dead
function squareIt($bar) {
return $bar ** 2;
$bar *= $bar;
return $bar;
}
Coding Horrors
Coding Horrors – The Ring (US
Remake)
Coding Horrors – The Ring (US
Remake)
DRY
Don’t Repeat Yourself
Coding Horrors
Coding Horrors – Chain Letter
Coding Horrors – Chain Letter
mysql> select * from users;
+----+----------+----------------------------------+-----------+
| id | username | password | followers |
+----+----------+----------------------------------+-----------+
| 1 | Shirley | 5f4dcc3b5aa765d61d8327deb882cf99 | 8,6,10 |
| 2 | Deborah | d1133275ee2118be63a577af759fc052 | 4 |
| 3 | Julie | 25d55ad283aa400af464c76d713c07ad | 4,5 |
| 4 | Jane | 4297f44b13955235245b2497399d7a93 | 3,5 |
| 5 | Jennifer | d8578edf8458ce06fbc5bb76a58c5ca4 | 3,4 |
| 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 |
| 7 | Philipa | 8621ffdbc5698829397d97767ac13db3 | NULL |
| 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 |
| 9 | Annabel | 0d107d09f5bbe40cade3de5c71e9e9b7 | 6 |
| 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 |
+----+----------+----------------------------------+-----------+
10 rows in set (0.00 sec)
Coding Horrors – Chain Letter
mysql> select * from users where followers like '%1%';
+----+----------+----------------------------------+-----------+
| id | username | password | followers |
+----+----------+----------------------------------+-----------+
| 1 | Shirley | 5f4dcc3b5aa765d61d8327deb882cf99 | 8,6,10 |
| 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 |
| 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 |
| 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 |
+----+----------+----------------------------------+-----------+
4 rows in set (0.00 sec)
Coding Horrors – Chain Letter
mysql> select * from users where followers like '%,1,%';
Empty set (0.00 sec)
mysql> select * from users
-> where followers = '1' or followers like '1,%' or followers like '%,1,%' or followers like '%,1';
+----+----------+----------------------------------+---------+
| id | username | password | friends |
+----+----------+----------------------------------+---------+
| 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 |
| 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 |
| 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 |
+----+----------+----------------------------------+---------+
3 rows in set (0.00 sec)
Coding Horrors – Chain Letter
mysql> select * from users where find_in_set(1,friends);
+----+----------+----------------------------------+---------+
| id | username | password | friends |
+----+----------+----------------------------------+---------+
| 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 |
| 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 |
| 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 |
+----+----------+----------------------------------+---------+
3 rows in set (0.00 sec)
Coding Horrors
Coding Horrors – The Mummy
Returns
Coding Horrors – The Mummy
Returns
$q = "SELECT id, name FROM test WHERE name like '%:foo%'";
$s = "carrot";
$sth = $dbh->prepare($q);
$sth->bindParam(':foo', $s);
$sth->execute();
Coding Horrors – The Mummy
Returns
$q = "SELECT id, name FROM test WHERE name like :foo";
$s = "carrot";
$s = "%{$s}%";
$sth = $dbh->prepare($q);
$sth->bindParam(':foo', $s);
$sth->execute();
Coding Horrors – The Mummy
Returns
$q = "SELECT * FROM posts WHERE post_title LIKE :q OR post_text LIKE :q";
$s = "carrot";
$s = "%{$s}%";
$sth = $dbh->prepare($q);
$sth->bindParam(':q', $s);
$sth->execute();
Coding Horrors – The Mummy
Returns
$q = "SELECT * FROM posts WHERE post_title LIKE :q1 OR post_text LIKE :q2";
$s = "carrot";
$s = "%{$s}%";
$sth = $dbh->prepare($q);
$sth->bindParam(':q1', $s);
$sth->bindParam(':q2', $s);
$sth->execute();
Coding Horrors
Coding Horrors – Halloween
Coding Horrors – Halloween
function monthList() {
$startDate = new DateTime();
$endDate = (clone $startDate)
->add(new DateInterval('P1Y'));
$dateRange = new DatePeriod($startDate, new DateInterval('P1M'), $endDate);
foreach($dateRange as $date) {
yield $date;
}
}
foreach(monthList() as $date) {
echo $date->format("M Y") . PHP_EOL;
}
Coding Horrors – Halloween
Jan 2018
Feb 2018
Mar 2018
Apr 2018
May 2018
Jun 2018
Jul 2018
Aug 2018
Sep 2018
Oct 2018
Nov 2018
Dec 2018
Jan 2018
Mar 2018
Apr 2018
May 2018
Jun 2018
Jul 2018
Aug 2018
Sep 2018
Oct 2018
Nov 2018
Dec 2018
Jan 2019
Coding Horrors – Halloween
function monthList() {
$startDate = new DateTime('first day of this month');
$endDate = (clone $startDate)
->add(new DateInterval('P1Y'));
$dateRange = new DatePeriod($startDate, new DateInterval('P1M'), $endDate);
foreach($dateRange as $date) {
yield $date;
}
}
foreach(monthList() as $date) {
echo $date->format("M Y") . PHP_EOL;
}
Coding Horrors
Coding Horrors – Alien
Coding Horrors – Alien
if (strpos(" " . $fileURL, "s3://") >= 1) {
// Do something
}
Coding Horrors – Alien
Coding Horrors – Alien
if (strpos($fileURL, "s3://") !== false) {
// Do something
}
Coding Horrors
Coding Horrors – Se7en
Coding Horrors – Se7en
$calendar = [
01 => 'January',
02 => 'February',
03 => 'March',
04 => 'April',
05 => 'May',
06 => 'June',
07 => 'July',
08 => 'August',
09 => 'September',
10 => 'October',
11 => 'November',
12 => 'December',
];
Coding Horrors – Se7en
1 => January
2 => February
3 => March
4 => April
5 => May
6 => June
7 => July
0 => September
10 => October
11 => November
12 => December
Coding Horrors – Se7en
$calendar = [
1 => 'January',
2 => 'February',
3 => 'March',
4 => 'April',
5 => 'May',
6 => 'June',
7 => 'July',
8 => 'August',
9 => 'September',
10 => 'October',
11 => 'November',
12 => 'December',
];
Coding Horrors
Coding Horrors – Pan’s Labyrinth
Coding Horrors – Pan’s Labyrinth
public function __construct(
MagentoFrameworkModelContext $context,
MagentoFrameworkViewDesignInterface $design,
MagentoFrameworkRegistry $registry,
MagentoStoreModelAppEmulation $appEmulation,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoFrameworkAppRequestInterface $request,
MagentoNewsletterModelTemplateFilter $filter,
MagentoFrameworkAppConfigScopeConfigInterface $scopeConfig,
MagentoNewsletterModelTemplateFactory $templateFactory,
MagentoFrameworkFilterFilterManager $filterManager,
array $data = []
) {
parent::__construct($context, $design, $registry, $appEmulation, $storeManager, $data);
$this->_storeManager = $storeManager;
$this->_request = $request;
$this->_filter = $filter;
$this->_scopeConfig = $scopeConfig;
$this->_templateFactory = $templateFactory;
$this->_filterManager = $filterManager;
}
Coding Horrors – Pan’s Labyrinth
The ideal number of arguments for a function is zero (niladic). Next
comes one (monadic) followed closely by two (dyadic). Three
arguments (triadic) should be avoided where possible. More than three
(polyadic) requires very special justification—and then shouldn't be
used anyway.
Bob Martin – “Clean Code”
Coding Horrors
Coding Horrors – Scream
Coding Horrors – Scream
$sql = "SELECT MAX(id) AS max_page FROM videos";
$result = @$conn->query($sql);
$row = @mysql_fetch_array($result);
echo $row["max_page"];
Coding Horrors – Scream
@dns_get_record();
dns_get_record();
Coding Horrors – Scream
Warning: dns_get_record() expects at least 1 parameter, 0 given in
%filename% on %line%
Coding Horrors – Scream
set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
if (error_reporting() === 0) {
// error was suppressed with the @-operator
throw new ErrorException(
'WHY ARE YOU SUPPRESSING ERRORS RATHER THAN HANDLING THEM!'
);
// return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
Coding Horrors – Scream
try {
@dns_get_record();
} catch (ErrorException $e) {
echo 'EXCEPTION: ', $e->getMessage(), PHP_EOL;
}
try {
dns_get_record();
} catch (ErrorException $e) {
echo 'EXCEPTION: ', $e->getMessage(), PHP_EOL;
}
Coding Horrors – Scream
EXCEPTION: WHY ARE YOU SUPPRESSING ERRORS RATHER THAN HANDLING THEM?
EXCEPTION: dns_get_record() expects at least 1 parameter, 0 given
Coding Horrors – Scream
Coding Horrors – Scream
• Scream
• PECL Extensions
• Disables the @ error control operator so that all errors are reported.
ini_set('scream.enabled', true);
Coding Horrors
Coding Horrors – Dawn of the Dead
Coding Horrors – Dawn of the Dead
/**
* Convert a date from PHP to Excel
*
* @param mixed $dateValue unix timestamp or datetime object
* @param string $timezone Optional timezone name for adjustment from UTC
* @return mixed Excel date/time value
**/
public function PHPToExcel(DateTimeImmutable $dateValue, DateTimeZone $timezone = null) {
// Do stuff
}
Coding
Horrors
Coding
Horrors
Who am I?
Mark Baker
Coordinator and Developer of:
Open Source PHPOffice library
PHPExcel (PHPSpreadsheet), PHPWord, PHPPresentation (formerly PHPPowerPoint), PHPProject, PHPVisio
Minor contributor to PHP core
@Mark_Baker
https://github.com/MarkBaker
http://uk.linkedin.com/pub/mark-baker/b/572/171
http://markbakeruk.net

More Related Content

PPT
An Elephant of a Different Colour: Hack
KEY
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
PDF
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
PDF
Taking Perl to Eleven with Higher-Order Functions
PDF
PHP 7 – What changed internally?
DOC
PDF
PHP 7 – What changed internally? (Forum PHP 2015)
PPTX
An Elephant of a Different Colour: Hack
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Taking Perl to Eleven with Higher-Order Functions
PHP 7 – What changed internally?
PHP 7 – What changed internally? (Forum PHP 2015)

What's hot (20)

TXT
Pop3ck sh
PPTX
Super Advanced Python –act1
PDF
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
PDF
{tidytext}と{RMeCab}によるモダンな日本語テキスト分析
TXT
Daily notes
PDF
Teaching Your Machine To Find Fraudsters
PPTX
Groovy puzzlers jug-moscow-part 2
PDF
PHP and MySQL Tips and tricks, DC 2007
PDF
Debugging: Rules And Tools - PHPTek 11 Version
KEY
Crazy things done on PHP
PDF
令和から本気出す
PDF
Doctrine fixtures
PDF
MongoDB全機能解説2
PDF
RxSwift 시작하기
PDF
How to stand on the shoulders of giants
PDF
MongoDBで作るソーシャルデータ新解析基盤
PDF
You Got Async in my PHP!
PDF
Adventures in Optimization
PDF
{tidygraph}と{ggraph}による モダンなネットワーク分析(未公開ver)
Pop3ck sh
Super Advanced Python –act1
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
{tidytext}と{RMeCab}によるモダンな日本語テキスト分析
Daily notes
Teaching Your Machine To Find Fraudsters
Groovy puzzlers jug-moscow-part 2
PHP and MySQL Tips and tricks, DC 2007
Debugging: Rules And Tools - PHPTek 11 Version
Crazy things done on PHP
令和から本気出す
Doctrine fixtures
MongoDB全機能解説2
RxSwift 시작하기
How to stand on the shoulders of giants
MongoDBで作るソーシャルデータ新解析基盤
You Got Async in my PHP!
Adventures in Optimization
{tidygraph}と{ggraph}による モダンなネットワーク分析(未公開ver)
Ad

Similar to Coding Horrors (20)

PPTX
Coding Horrors
PDF
veracruz
PDF
veracruz
PDF
veracruz
PDF
veracruz
PDF
lab4_php
PDF
lab4_php
PPT
Php introduction
PDF
•Design (create) 3 questions for a quiz show game and design regular.pdf
PDF
Patterns / Antipatterns with NoSQL
PDF
Presenter manual php and mysql with cms (specially for summer interns)
PDF
PHP and Databases
PPTX
Database Connectivity MYSQL by Dr.C.R.Dhivyaa Kongu Engineering College
PPTX
UNIT V (5).pptx
ODP
Php 102: Out with the Bad, In with the Good
PDF
PostgreSQL Modules Tutorial - chkpass, hstore, fuzzystrmach, isn
PPT
Download It
PPT
Php course-in-navimumbai
PPT
Php mysql
PPTX
CVJ531: Intro to MySQL
Coding Horrors
veracruz
veracruz
veracruz
veracruz
lab4_php
lab4_php
Php introduction
•Design (create) 3 questions for a quiz show game and design regular.pdf
Patterns / Antipatterns with NoSQL
Presenter manual php and mysql with cms (specially for summer interns)
PHP and Databases
Database Connectivity MYSQL by Dr.C.R.Dhivyaa Kongu Engineering College
UNIT V (5).pptx
Php 102: Out with the Bad, In with the Good
PostgreSQL Modules Tutorial - chkpass, hstore, fuzzystrmach, isn
Download It
Php course-in-navimumbai
Php mysql
CVJ531: Intro to MySQL
Ad

More from Mark Baker (20)

PPTX
Looping the Loop with SPL Iterators
PPTX
Looping the Loop with SPL Iterators
PPTX
Looping the Loop with SPL Iterators
PPTX
Deploying Straight to Production
PPTX
Deploying Straight to Production
PPTX
Deploying Straight to Production
PPTX
A Brief History of Elephpants
PPTX
Aspects of love slideshare
PPTX
Does the SPL still have any relevance in the Brave New World of PHP7?
PPTX
A Brief History of ElePHPants
PPTX
Anonymous classes2
PPTX
Testing the Untestable
PPTX
Anonymous Classes: Behind the Mask
PPTX
Does the SPL still have any relevance in the Brave New World of PHP7?
PPTX
Does the SPL still have any relevance in the Brave New World of PHP7?
PPTX
Giving birth to an ElePHPant
PPTX
A Functional Guide to Cat Herding with PHP Generators
PPTX
A Functional Guide to Cat Herding with PHP Generators
PPTX
SPL - The Undiscovered Library - PHPBarcelona 2015
PPTX
Zephir - A Wind of Change for writing PHP extensions
Looping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
Deploying Straight to Production
Deploying Straight to Production
Deploying Straight to Production
A Brief History of Elephpants
Aspects of love slideshare
Does the SPL still have any relevance in the Brave New World of PHP7?
A Brief History of ElePHPants
Anonymous classes2
Testing the Untestable
Anonymous Classes: Behind the Mask
Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?
Giving birth to an ElePHPant
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
SPL - The Undiscovered Library - PHPBarcelona 2015
Zephir - A Wind of Change for writing PHP extensions

Recently uploaded (20)

PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
System and Network Administraation Chapter 3
PPTX
ai tools demonstartion for schools and inter college
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
top salesforce developer skills in 2025.pdf
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
PTS Company Brochure 2025 (1).pdf.......
PPTX
L1 - Introduction to python Backend.pptx
PDF
medical staffing services at VALiNTRY
PDF
AI in Product Development-omnex systems
PPTX
CHAPTER 2 - PM Management and IT Context
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
How Creative Agencies Leverage Project Management Software.pdf
System and Network Administraation Chapter 3
ai tools demonstartion for schools and inter college
wealthsignaloriginal-com-DS-text-... (1).pdf
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Design an Analysis of Algorithms II-SECS-1021-03
VVF-Customer-Presentation2025-Ver1.9.pptx
Odoo POS Development Services by CandidRoot Solutions
top salesforce developer skills in 2025.pdf
Operating system designcfffgfgggggggvggggggggg
Odoo Companies in India – Driving Business Transformation.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PTS Company Brochure 2025 (1).pdf.......
L1 - Introduction to python Backend.pptx
medical staffing services at VALiNTRY
AI in Product Development-omnex systems
CHAPTER 2 - PM Management and IT Context

Coding Horrors

  • 1. Coding Horrors A Horror Film Fan’s Guide to PHP Coding Nightmares
  • 4. Coding Horrors – Friday the 13th
  • 5. Coding Horrors – Friday the 13th // 3 month appointments $date_to = date('d/m/Y'); $date_from = date("d/m/Y", strtotime(" +3 months")); $get = "select * from appointments where date between '$date_from' and '$date_to'"; $get_connect = mysqli_query($con2, $get); $get_rows = mysqli_num_rows($get_connect);
  • 6. Coding Horrors – Friday the 13th mysql> select * from appointments; +----+-----------+------------------------+ | id | date | appointment | +----+-----------+------------------------+ | 1 | 2/1/2018 | PHPNW January meetup | | 2 | 6/2/2018 | PHPNW February Meetup | | 3 | 6/3/2018 | PHPNW March Meetup | | 4 | 3/4/2018 | PHPNW April Meetup | | 5 | 1/5/2018 | PHPNW May Meetup | | 6 | 5/6/2018 | PHPNW June Meetup | | 7 | 3/7/2018 | PHPNW July Meetup | | 8 | 7/8/2018 | PHPNW August Meetup | | 9 | 4/9/2018 | PHPNW September Meetup | | 10 | 2/10/2018 | PHPNW October Meetup | | 11 | 6/11/2018 | PHPNW November Meetup | | 12 | 4/12/2018 | PHPNW December Meetup | +----+-----------+------------------------+ 12 rows in set (0.01 sec) mysql> select * from appointments -> where date between '2/1/2018' and '5/1/2018’; +----+-----------+------------------------+ | id | date | appointment | +----+-----------+------------------------+ | 1 | 2/1/2018 | PHPNW January meetup | | 4 | 3/4/2018 | PHPNW April Meetup | | 7 | 3/7/2018 | PHPNW July Meetup | | 9 | 4/9/2018 | PHPNW September Meetup | | 10 | 2/10/2018 | PHPNW October Meetup | | 12 | 4/12/2018 | PHPNW December Meetup | +----+-----------+------------------------+ 6 rows in set (0.00 sec)
  • 9. Coding Horrors – The Ring $studentArray = array(); $query1 = "SELECT * FROM students ORDER BY name"; $studentList = mysqli_query($conn,$query1) or die ("cannot query the table1: " . mysqli_error($conn)); while ($student = mysqli_fetch_array($studentList)) { $studentId = $student['id']; $courses = array(); $query2 = "SELECT * FROM classes WHERE studentid='$studentId'"; $classList = mysqli_query($conn,$query2) or die ("cannot query the table2: " . mysqli_error($conn)); while ($class = mysqli_fetch_array($classList)) { array_push($classes, $class['name']); } array_push($studentArray, array($studentId, $student['name'], implode(', ', $classes))); }
  • 10. Coding Horrors – The Ring SELECT s.id, s.name, group_concat(c.name separator ', ') FROM students s LEFT JOIN classes c ON c.studentid = s.id GROUP BY s.id, s.name ORDER BY s.name;
  • 11. Coding Horrors – The Ring SELECT s.id, s.name, c.name FROM students s LEFT JOIN classes c ON c.studentid = s.id GROUP BY s.id, s.name ORDER BY s.name;
  • 13. Coding Horrors – The Mummy
  • 14. Coding Horrors – The Mummy $Data = $connection->prepare( "SELECT * FROM :TableName ORDER BY :OrderByColumn :OrderDirection LIMIT 10 OFFSET :Offset" ); $Data->bindValue(':TableName', $TableName, PDO::PARAM_STR); $Data->bindValue(':Offset', $Offset, PDO::PARAM_INT); $Data->bindValue(':OrderByColumn', $OrderColumn, PDO::PARAM_STR); $Data->bindValue(':OrderDirection', $OrderDirection, PDO::PARAM_STR); $Data->execute();
  • 16. Coding Horrors – Night of the Living Dead
  • 17. Coding Horrors – Night of the Living Dead function getAddressDetails() { $data->name = 'Mark'; // $data->address = 'mi casa'; // $data->city = 'Manchester'; // $data->country = 'UK'; // return json_encode($data, JSON_UNESCAPED_UNICODE); return json_encode($data); }
  • 18. Coding Horrors – Night of the Living Dead function getAddressDetails() { $data->name = 'Mark’; return json_encode($data); } git commit -m "Remove address, which is now accessed through a separate API call"
  • 19. Coding Horrors – Night of the Living Dead function addValues($a, $b, $options) { $sum = 0; return $a + $b; }
  • 20. Coding Horrors – Night of the Living Dead function squareIt($bar) { return $bar ** 2; $bar *= $bar; return $bar; }
  • 22. Coding Horrors – The Ring (US Remake)
  • 23. Coding Horrors – The Ring (US Remake) DRY Don’t Repeat Yourself
  • 25. Coding Horrors – Chain Letter
  • 26. Coding Horrors – Chain Letter mysql> select * from users; +----+----------+----------------------------------+-----------+ | id | username | password | followers | +----+----------+----------------------------------+-----------+ | 1 | Shirley | 5f4dcc3b5aa765d61d8327deb882cf99 | 8,6,10 | | 2 | Deborah | d1133275ee2118be63a577af759fc052 | 4 | | 3 | Julie | 25d55ad283aa400af464c76d713c07ad | 4,5 | | 4 | Jane | 4297f44b13955235245b2497399d7a93 | 3,5 | | 5 | Jennifer | d8578edf8458ce06fbc5bb76a58c5ca4 | 3,4 | | 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 | | 7 | Philipa | 8621ffdbc5698829397d97767ac13db3 | NULL | | 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 | | 9 | Annabel | 0d107d09f5bbe40cade3de5c71e9e9b7 | 6 | | 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 | +----+----------+----------------------------------+-----------+ 10 rows in set (0.00 sec)
  • 27. Coding Horrors – Chain Letter mysql> select * from users where followers like '%1%'; +----+----------+----------------------------------+-----------+ | id | username | password | followers | +----+----------+----------------------------------+-----------+ | 1 | Shirley | 5f4dcc3b5aa765d61d8327deb882cf99 | 8,6,10 | | 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 | | 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 | | 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 | +----+----------+----------------------------------+-----------+ 4 rows in set (0.00 sec)
  • 28. Coding Horrors – Chain Letter mysql> select * from users where followers like '%,1,%'; Empty set (0.00 sec) mysql> select * from users -> where followers = '1' or followers like '1,%' or followers like '%,1,%' or followers like '%,1'; +----+----------+----------------------------------+---------+ | id | username | password | friends | +----+----------+----------------------------------+---------+ | 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 | | 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 | | 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 | +----+----------+----------------------------------+---------+ 3 rows in set (0.00 sec)
  • 29. Coding Horrors – Chain Letter mysql> select * from users where find_in_set(1,friends); +----+----------+----------------------------------+---------+ | id | username | password | friends | +----+----------+----------------------------------+---------+ | 6 | Alison | 827ccb0eea8a706c4c34a16891f84e7b | 9,1 | | 8 | Sue | acc6f2779b808637d04c71e3d8360eeb | 1 | | 10 | Cathy | 5badcaf789d3d1d09794d8f021f40f0e | 3,1 | +----+----------+----------------------------------+---------+ 3 rows in set (0.00 sec)
  • 31. Coding Horrors – The Mummy Returns
  • 32. Coding Horrors – The Mummy Returns $q = "SELECT id, name FROM test WHERE name like '%:foo%'"; $s = "carrot"; $sth = $dbh->prepare($q); $sth->bindParam(':foo', $s); $sth->execute();
  • 33. Coding Horrors – The Mummy Returns $q = "SELECT id, name FROM test WHERE name like :foo"; $s = "carrot"; $s = "%{$s}%"; $sth = $dbh->prepare($q); $sth->bindParam(':foo', $s); $sth->execute();
  • 34. Coding Horrors – The Mummy Returns $q = "SELECT * FROM posts WHERE post_title LIKE :q OR post_text LIKE :q"; $s = "carrot"; $s = "%{$s}%"; $sth = $dbh->prepare($q); $sth->bindParam(':q', $s); $sth->execute();
  • 35. Coding Horrors – The Mummy Returns $q = "SELECT * FROM posts WHERE post_title LIKE :q1 OR post_text LIKE :q2"; $s = "carrot"; $s = "%{$s}%"; $sth = $dbh->prepare($q); $sth->bindParam(':q1', $s); $sth->bindParam(':q2', $s); $sth->execute();
  • 37. Coding Horrors – Halloween
  • 38. Coding Horrors – Halloween function monthList() { $startDate = new DateTime(); $endDate = (clone $startDate) ->add(new DateInterval('P1Y')); $dateRange = new DatePeriod($startDate, new DateInterval('P1M'), $endDate); foreach($dateRange as $date) { yield $date; } } foreach(monthList() as $date) { echo $date->format("M Y") . PHP_EOL; }
  • 39. Coding Horrors – Halloween Jan 2018 Feb 2018 Mar 2018 Apr 2018 May 2018 Jun 2018 Jul 2018 Aug 2018 Sep 2018 Oct 2018 Nov 2018 Dec 2018 Jan 2018 Mar 2018 Apr 2018 May 2018 Jun 2018 Jul 2018 Aug 2018 Sep 2018 Oct 2018 Nov 2018 Dec 2018 Jan 2019
  • 40. Coding Horrors – Halloween function monthList() { $startDate = new DateTime('first day of this month'); $endDate = (clone $startDate) ->add(new DateInterval('P1Y')); $dateRange = new DatePeriod($startDate, new DateInterval('P1M'), $endDate); foreach($dateRange as $date) { yield $date; } } foreach(monthList() as $date) { echo $date->format("M Y") . PHP_EOL; }
  • 43. Coding Horrors – Alien if (strpos(" " . $fileURL, "s3://") >= 1) { // Do something }
  • 45. Coding Horrors – Alien if (strpos($fileURL, "s3://") !== false) { // Do something }
  • 48. Coding Horrors – Se7en $calendar = [ 01 => 'January', 02 => 'February', 03 => 'March', 04 => 'April', 05 => 'May', 06 => 'June', 07 => 'July', 08 => 'August', 09 => 'September', 10 => 'October', 11 => 'November', 12 => 'December', ];
  • 49. Coding Horrors – Se7en 1 => January 2 => February 3 => March 4 => April 5 => May 6 => June 7 => July 0 => September 10 => October 11 => November 12 => December
  • 50. Coding Horrors – Se7en $calendar = [ 1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December', ];
  • 52. Coding Horrors – Pan’s Labyrinth
  • 53. Coding Horrors – Pan’s Labyrinth public function __construct( MagentoFrameworkModelContext $context, MagentoFrameworkViewDesignInterface $design, MagentoFrameworkRegistry $registry, MagentoStoreModelAppEmulation $appEmulation, MagentoStoreModelStoreManagerInterface $storeManager, MagentoFrameworkAppRequestInterface $request, MagentoNewsletterModelTemplateFilter $filter, MagentoFrameworkAppConfigScopeConfigInterface $scopeConfig, MagentoNewsletterModelTemplateFactory $templateFactory, MagentoFrameworkFilterFilterManager $filterManager, array $data = [] ) { parent::__construct($context, $design, $registry, $appEmulation, $storeManager, $data); $this->_storeManager = $storeManager; $this->_request = $request; $this->_filter = $filter; $this->_scopeConfig = $scopeConfig; $this->_templateFactory = $templateFactory; $this->_filterManager = $filterManager; }
  • 54. Coding Horrors – Pan’s Labyrinth The ideal number of arguments for a function is zero (niladic). Next comes one (monadic) followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn't be used anyway. Bob Martin – “Clean Code”
  • 57. Coding Horrors – Scream $sql = "SELECT MAX(id) AS max_page FROM videos"; $result = @$conn->query($sql); $row = @mysql_fetch_array($result); echo $row["max_page"];
  • 58. Coding Horrors – Scream @dns_get_record(); dns_get_record();
  • 59. Coding Horrors – Scream Warning: dns_get_record() expects at least 1 parameter, 0 given in %filename% on %line%
  • 60. Coding Horrors – Scream set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) { if (error_reporting() === 0) { // error was suppressed with the @-operator throw new ErrorException( 'WHY ARE YOU SUPPRESSING ERRORS RATHER THAN HANDLING THEM!' ); // return false; } throw new ErrorException($errstr, 0, $errno, $errfile, $errline); });
  • 61. Coding Horrors – Scream try { @dns_get_record(); } catch (ErrorException $e) { echo 'EXCEPTION: ', $e->getMessage(), PHP_EOL; } try { dns_get_record(); } catch (ErrorException $e) { echo 'EXCEPTION: ', $e->getMessage(), PHP_EOL; }
  • 62. Coding Horrors – Scream EXCEPTION: WHY ARE YOU SUPPRESSING ERRORS RATHER THAN HANDLING THEM? EXCEPTION: dns_get_record() expects at least 1 parameter, 0 given
  • 64. Coding Horrors – Scream • Scream • PECL Extensions • Disables the @ error control operator so that all errors are reported. ini_set('scream.enabled', true);
  • 66. Coding Horrors – Dawn of the Dead
  • 67. Coding Horrors – Dawn of the Dead /** * Convert a date from PHP to Excel * * @param mixed $dateValue unix timestamp or datetime object * @param string $timezone Optional timezone name for adjustment from UTC * @return mixed Excel date/time value **/ public function PHPToExcel(DateTimeImmutable $dateValue, DateTimeZone $timezone = null) { // Do stuff }
  • 70. Who am I? Mark Baker Coordinator and Developer of: Open Source PHPOffice library PHPExcel (PHPSpreadsheet), PHPWord, PHPPresentation (formerly PHPPowerPoint), PHPProject, PHPVisio Minor contributor to PHP core @Mark_Baker https://github.com/MarkBaker http://uk.linkedin.com/pub/mark-baker/b/572/171 http://markbakeruk.net

Editor's Notes

  • #4: Friday the 13th
  • #5: Using varchar for dates in a database table
  • #6: Varchar fields for dates/times in a database, especially when using d/m/Y or m/d/Y formats for storage
  • #7: Can work when using Y-m-d format Please use appropriate date datatypes
  • #8: The Ring (original Japanese version, not the US remake)
  • #10: Unnecessary (and expensive) loops
  • #11: Single database query to achieve the same result
  • #12: Single database query to achieve the same result
  • #13: The Mummy (1999 version)
  • #15: Misunderstood bindings
  • #16: Night of the Living Dead
  • #18: This is what your version control is for! And if you have to leave commented code in your files, then provide an explanation of why it is commented out.
  • #19: This is what your version control is for! And if you have to leave commented code in your files, then provide an explanation of why it is commented out.
  • #20: Static Analysis tools should pick these up Don’t rely on PHP’s opcache optimisation to clean up the redundant code, it still impairs readability, and won’t clean up the unused but mandatory $options argument
  • #21: Static Analysis tools should pick this up too
  • #22: The Ring (US Remake)
  • #23: There are times when you simply shouldn’t try to copy a great original
  • #25: Chain Letter
  • #26: A real turkey
  • #27: Besides the md5 hashed passwords Comma-separated list of ids in a column
  • #28: Common approach
  • #29: Common approach
  • #30: This is so common that MySQL even provides a “syntactic sugar” function to help But it still can’t use indexes and entails a full table scan Better yet, normalize your table structures
  • #31: The Mummy Returns
  • #32: More binding misunderstandings
  • #35: Can’t duplicate the same named parameter
  • #36: Can’t duplicate the same named parameter
  • #37: Halloween
  • #39: 31st of October
  • #41: 31st of October
  • #42: Alien
  • #44: This code actually works without issue;
  • #45: BUT the PHP Docs are pretty explicit here....
  • #46: Symptomatic of a developer that doesn't understand basic PHP Functions, comparisons and datatypes; and/or didn't read the PHP Documentation: when you find an issue like this nesting in the codebase, there are certain to be other problems.
  • #47: Se7en
  • #48: Seven is the highest digit in octal notation
  • #49: Gives a "Parse error: Invalid numeric literal" in PHP7.... What do you mean you're not running php7 yet?
  • #50: Gives a "Parse error: Invalid numeric literal" in PHP7.... What do you mean you're not running php7 yet?
  • #51: Gives a "Parse error: Invalid numeric literal" in PHP7.... What do you mean you're not running php7 yet?
  • #52: Pan’s Labyrinth
  • #56: Scream
  • #58: Besides the inefficiency of suppressing the errors, this also hides problems
  • #59: Besides the inefficiency of suppressing the errors, this also hides problems Error handling is still called, but with error reporting temporarily set to 0
  • #60: Only the unsuppressed call display a warning
  • #61: If we set an error handler, we can process that warning cleanly, converting it to a catchable Exception if we want
  • #63: Besides the inefficiency of suppressing the errors, this also hides problems
  • #64: Besides the inefficiency of suppressing the errors, this also hides problems
  • #65: Besides the inefficiency of suppressing the errors, this also hides problems
  • #66: Dawn of the Dead
  • #68: Docblocks are no longer in synch with the code Building the docs should highlight this mismatch
  • #69: Don’t let these code smells come back to haunt you again and again
  • #70: But exorcise them when you find them