Types in PHP and MySQL

Since PHP 7.0 has been released there’s more attention on scalar types. Keeping types for data from within your application is relatively simple. But when talking to external systems, like a database things aren’t always as one eventually might initially expect.

For MySQL the type we see — in the first approximation — is defined by the network protocol. The MySQL network protocol by default converts all data into strings. So if we fetch an integer from the database and use PHP 7’s typing feature we get an error:

<?php
declare(strict_types=1);

function getInteger() : int {
  $mysqli = new mysqli(...);
  return $mysqli->query("SELECT 1")->fetch_row()[0];
}

var_dump(getInteger());
?>

Fatal error: Uncaught TypeError: Return value of getInteger() must be of the type integer, string returned in t.php:6

Of course the solution is easy: Either we cast ourselves or we disable the strict mode and PHP will cast for us.

Now let’s take a look at another case. Assume we have an application where we fetch an integer ID from the database. We know MySQL will send us a string and we treat the ID as opaque data anyways so we have the type check for a string. Now we refactor the code slightly and make use of prepared statements. What will the result be?

<?php
declare(strict_types=1);

function getId() : string {
  $mysqli = new mysqli(...);
  $stmt = $mysqli->prepare("SELECT 1");
  $stmt->execute();
  return $stmt->get_result()->fetch_row()[0];
}

var_dump(getId());
?>

Fatal error: Uncaught TypeError: Return value of getId() must be of the type string, integer returned in t.php:8

Wait! – What’s up there!? — Didn’t I just say that the MySQL protocol will always send a string, thus we retrieve a string in PHP!? – Yes I did and that’s true for "direct queries." It’s not true for results from prepared statements. With prepared statements the MySQL protocol uses a binary encoding of the data and therefore mysqlnd and mysqli will try to find the matching PHP type. This isn’t always possible, especially if we’re going into the range of big values. So let’s query for PHP_INT_MAX and PHP_INT_MAX+1 and look at the types:

<?php
$mysqli = new mysqli(...);
$stmt = $mysqli->prepare("SELECT 9223372036854775807, 9223372036854775808");
$stmt->execute();
var_dump($stmt->get_result()->fetch_row());
?>

array(2) {
  [0]=>
  int(9223372036854775807)
  [1]=>
  string(19) "9223372036854775808"
}

Here 9223372036854775807 is the largest value a PHP integer can represent and thus is an integer. 9223372036854775808 however is to large and can’t fit in a signed 64bit integer thus it is converted in a string, as this keeps all information and can be handled at least to some degree.

Similar things happens to other types which can’t be properly represented in PHP:

<?php
$mysqli = new mysqli(...);
$stmt = $mysqli->prepare("SELECT 1.23");
$stmt->execute();
var_dump($stmt->get_result()->fetch_row());
?>

array(2) {
  [0]=>
  string(4) "1.23"
}

Yay – yet another wtf! So what is going on this time? — Well, a literal in SQL is treated as DECIMAL. A DECIMAL field is supposed to be precise. If this were to be converted into a PHP float aka. double we probably would loose the precision, thus treating it as string again makes sure we’re not loosing information. If we had a FLOAT or DOUBLE field this could safely be represented as float in PHP:

<?php
$mysqli = new mysqli(...);
$stmt = $mysqli->prepare("SELECT RAND()");
$stmt->execute();
var_dump($stmt->get_result()->fetch_row());
?>

array(2) {
  [0]=>
  float(0.16519711461402206)
}

So to summarize:

  • For a direct query the MySQL server sends strings, PHP returns all data as string
  • For prepared statements MySQL sends data in binary form and PHP will use a corresponding type
  • If the value could only be represented with a potential data loss in PHP it is converted to a string by PHP, even with prepared statements

Now we might expect the same when using PDO. Let’s check:

<?php
$pdo = new PDO("mysql:host=localhost", "...", "...");
$stmt = $pdo->prepare("SELECT 9223372036854775808, RAND()");
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_NUM));
?>

array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(18) "0.3217373297752229"
}

This example uses prepared statements, but returns strings!? The reason is that PDO by default doesn’t use prepared statements on the network layer but an emulation within PHP. This means PHP will replace potential placeholders and then runs a direct query. As mentioned above with a direct query the MySQL server will send strings, thus PHP will represent all data as string. However we can easily ask PDO to disable the emulation:

<?php
$pdo = new PDO("mysql:host=localhost", "...", "...");
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $pdo->prepare("SELECT 1, RAND()");
$stmt->execute();
var_dump($stmt->fetch(PDO::FETCH_NUM));
?>

array(2) {
  [0]=>
  int(1)
  [1]=>
  float(0.24252333421495)
}

This leaves the question whether you should disable the emulation in order to get the correct types. Doing this has some impact on performance characteristics: With native prepared statements there will be a client-server round-trip during the prepare and another round-trip for the execute. With emulation only during the execute. The native prepared statements also require some server resources to store the handle. However if a single statement is executed multiple times there might be some savings. Also the type representation means that different type conversions happen and a different amount of data is transfered. For most cases this shouldn’t have notable impact, but in the end only a benchmark will tell.

Hope this helps to give a better understanding, or more confusion :-)

PlanetMySQL Voting: Vote UP / Vote DOWN
via Planet MySQL
Types in PHP and MySQL

Stanford Professor puts his entire digital photography course online for free

Stanford Professor puts his entire digital photography course online for free

Marc Levoy is one of those names that belongs right near the top. His work has led to a lot of the technical advances that we see in use today with computer generated imagery. So, it’s no wonder that he jumped into digital photography. From 2009 until 2014, Levoy taught digital photography at Stanford.

In 2016, he revised the course and taught it again at Google in Spring. Now, the entire revised course is available online completely free. The course assumes no prior knowledge of photography whatsoever. It covers pretty much everything you’d ever want to know about photography. Covering a multitude of technical aspects from the basics to extremely in-depth.

There’s hours and hours of video covering Levoy’s lectures to Google over a 4 month period. Several web based apps are there, too, to help understand some of the trickier technical concepts of photography. He also provides several assignments to help you challenge yourself and put what you’ve learned to good use.

It’s a whole hell of a lot of stuff to read and watch. From what I’ve seen so far, it’s well worth watching it all.

You can find the entire course for free here. If you have any interest at all in the technical side of photography (you should), then what are you waiting for? Get stuck in!

via DIYPhotography.net – Photography and Studio Lighting – Do It Yourself
Stanford Professor puts his entire digital photography course online for free

DIY Laser Zapper

DIY Laser Zapper

Link

Seb Lee-Delisle modified a Nintendo Zapper to fire laser beams and even have smoke come out of the barrel with each shot. It has a pair of LEDs, a laser module, and a vape module. The light effects on the wall are from a separate projector.

via The Awesomer
DIY Laser Zapper

Brilliant Hacker Turned the Classic NES Zapper Into a Kick-Ass Toy Laser Gun

Brilliant Hacker Turned the Classic NES Zapper Into a Kick-Ass Toy Laser Gun

For the upcoming ‘Hacked on Classics’ show being held as part of the Brighton Digital Festival in the UK this month, hacker Seb Lee-Delisle modified the classic NES’ Zapper accessory with LEDs, a green laser, the smoke-generating parts from an e-cigarette, and a small blower to create the convincing effect of a functional laser pistol.

All of the electronic elements added to the NES Zapper are perfectly timed to create the illusion of it firing actual laser blasts, including a quick puff of smoke to make the laser’s beam visible as it leaves the barrel. For the exploding burst that appears on the wall, a separate computer-controlled laser uses a camera to estimate where the Zapper is pointed, creating a simulated point of impact after the trigger has been pulled.

Don’t pretend for a second that you aren’t making “pew-pew” sound effects in your head while watching that video.

[Seb Lee-Delisle via Hackaday]

via Gizmodo
Brilliant Hacker Turned the Classic NES Zapper Into a Kick-Ass Toy Laser Gun

Netflix’s New “Slow TV” Shows are Meditative and Chill

If you really want a little chill with your Netflix, the service just added a bunch of “slow TV” shows, things like long train rides through the countryside, relaxing views of canal rides, crackling fireplaces, quiet video of people knitting, and so on. They’re all things you can put on in the background while you work, focus, or just relax.

“Slow TV,” as Kottke describes here is just the airing of a completely ordinary event from start to finish (much like our own Facebook Live “Lunchtime Views” series.) Here’s what you can tune into if you’re looking for something maybe a little ASMR, or maybe just super chill and not-at-all-attention grabbing:

National Firewood Evening
National Firewood Morning
National Firewood Night
National Knitting Evening
National Knitting Morning
National Knitting Night
Northern Passage
Northern Railway
Salmon Fishing
The Telemark Canal
Train Ride Bergen to Oslo

If you’re noticing a Scandinavian thrust to some of these, it’s intentional—a lot of these programs really caught on in Norway, so that’s where Netflix is getting them from. Some of them aren’t exactly the same end-to-end shows that were originally aired, if you’re familiar with them, but they’re enough to help you relax a little after a long day. Hit the link below to read a bit more about them.

Slow TV comes to Netflix | Kottke

via Lifehacker
Netflix’s New “Slow TV” Shows are Meditative and Chill

Google Car Captures Guy’s Awful Day at Work for All Eternity

We’ve all had bad days at work, but most of us can just soldier through and move on. Unfortunately for Joshua Justice, Google Street View will never let him forget one particularly terrible shift.

Two months ago, Justice was working at Houston’s Flying Saucer Draught Emporium when he spilled “half a cleaning keg” on his pants. From there, it only got worse.

“Went outside to stand in the sun … as a Google maps car drove by,” wrote Justice on Facebook at time. “Look for me on Street View soon. I’ll be the guy that looks like he pissed himself.”

On Tuesday, Justice discovered that Google had recently updated Street View. Just as he predicted, him and his seemingly pissy pants were there for the whole world to see.

Of course, it’s possible Justice really did wet himself and concocted the elaborate tale to cover up the incident, but even if that’s true, hasn’t he suffered enough?

[Houstonia]

via Gizmodo
Google Car Captures Guy’s Awful Day at Work for All Eternity

Watch a High-Powered Cleaning Laser Annihilate Everything in Its Path


GIF

The next time you’re staring down a tough cleaning job—be it removing paint, rust, or lasagna off of a baking dish—don’t waste your time with harsh chemicals, sand paper, or scrubbers. Get yourself a 1,000-watt laser and blast away that filth and grime in just seconds.

Judging by this video, the first company to make a laser dishwasher that actually gets dishes clean, without pre-rinsing, is going to make a small fortune.

[YouTube via Likecool]

via Gizmodo
Watch a High-Powered Cleaning Laser Annihilate Everything in Its Path