Looking at the source code for QRcode::png()
, I can see that it sends a Content-Type
header prior to displaying the PNG image data. That is necessary to inform the receiving browser or device that the data is a PNG image.
// Excerpted from source:
if ($filename === false) {
Header("Content-type: image/png");
ImagePng($image);
// etc...
https://github.com/t0k4rt/phpqrcode/blob/f0567ce717fa1172cb66c48ebae017a094de64b1/qrimage.php#L30
If you have leading whitespace before the opening <?php
or any output of any kind before that function is called, PHP will not be able to send the necessary headers.
For full details on this issue and all its potential causes, see How to fix Headers already sent errors in PHP.
Always when developing and testing code, ensure that you have enabled PHP's error display. If it were on, you would have seen PHP issuing warnings related to headers already being sent.
Warning: Cannot modify header information - headers already sent by....etc...
// At the very top of your script:
error_reporting(E_ALL);
ini_set('display_errors', 1);
Or set error_reporting
and display_errors
in your php.ini. The fact that you saw no errors in your log suggests you either have log_errors
disabled in php.ini, or a conservative setting for error_reporting
which is not reporting on E_WARNING
errors. Best to use E_ALL
.
Update after code posted:
You have attempted to call QRcode::png()
inside the same script which is currently generating your HTML page. You can't actually do that, because the QR code has to be generated and inserted into an <img>
tag. Even though it is generated at runtime by PHP, from the browser's perspective it isn't any different from a real image read from a file on disk so you have to use it the same way in HTML markup as you would a file from disk.
The easiest method to handle this properly is to move the QR code generation to a different PHP file where it is the only action taking place. Then reference that file in an <img>
tag's src
.
File: generate_qrcode.php
This PHP script is intended to be referenced as example.com/generate_qrcode.php?myid=abcdefg
. If you called it as such from the browser, it should just display the bare QR code.
// Contains only QR generation
// Move the $code here, and pass the myid in the query string
// Also move the function definition here
function generateRandomCode() {
// whatever...
}
$code = generateRandomCode();
// This value was originally POSTed to the main script, so
// it needs to be passed from the main script to this one via the query string
$myid = $_GET['myid'];
$tem = '"myid":"' . $myid . '","code":"' . $code . '"}';
include('../../lib/qrlib.php');
QRcode::png($tem);
Main PHP file:
To really use it the way you want in context of your HTML page requires an <img>
tag though.
Include an <img>
tag which sources the QR code and passes $myid
in its query string. The PHP/HTML should not call QRcode::png()
itself.
<img src="generate_qrcode.php?myid=<?php echo htmlspecialchars($myid); ?>" alt="QR code" />
This would result in a tag like <img src="generate_qrcode.php?myid=abcdefg" alt="QR code" />
For full context, your main script would now look like:
<!DOCTYPE HTML>
<html>
<head>
<style>
.error {color: #FF0000;}
</style>
</head>
<body>
<?php
$myErr = "";
$myid = "";
// This function is defined instead in the QR code script...
//function generateRandomCode() {
// returns random code
//}
// POST handling is the same!
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["myid"])) {
$myidErr = "myID is required";
}
// But this is done in the other QR code script
//$code = generateRandomCode();
}
?>
<h2>My Project</h2>
<!-- The form is the same! -->
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
My ID: <input type="text" name="myid" value="">
<span class="error">* <?php echo $myidErr;?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>
<?php
if ($myid) {
echo "<h2>QR Code:</h2>";
// Now include an <img> tag
echo "<img src='generate_qrcode.php?myid=$myid' alt='QR code' />";
}
?>