1

I've below working code in PHP

<?php
         include('../../lib/qrlib/qrlib.php');

         QRcode::png('PHP QR Codep :)');
?>

The weird part is if I put a space in front of

 <?php

then the same code does not work & error log does not show any details either. Also, if I put any other function in the top code before this code, the QR code does not get generated. No error in log either.

What am I missing here???

Update:

Here is my code:

<!DOCTYPE HTML>
<html>
    <head>
        <style>
        .error {color: #FF0000;}
        </style>
    </head>
    <body>
        <?php
            $myErr = "";
            $myid = "";

            function generateRandomCode() {
                // returns random code
            }

            if ($_SERVER["REQUEST_METHOD"] == "POST") {
                if (empty($_POST["myid"])) {
                    $myidErr = "myID is required";
                } 

                $code = generateRandomCode();
            }
        ?>

        <h2>My Project</h2>     

        <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
            echo "<h2>QR Code:</h2>";

            $tem = '"myid":"' . $myid . '","code":"' . $code . '"}';


            include('../../lib/qrlib.php');
            QRcode::png($tem);
        ?>
    </body>
</html>
Jack
  • 53
  • 1
  • 1
  • 6

1 Answers1

3

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' />";
            }
        ?>
Community
  • 1
  • 1
Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
  • +1 because the issue is exactly as stated here. You can't send **any** input before trying to send headers. – Darren Nov 05 '14 at 01:11
  • Miachael, thanks for explaination but I'm still unclear on how to fix the issue. I've other functions as well before putting this QR code, how can I fix this? – Jack Nov 05 '14 at 01:20
  • Michael, I added the code in original question. Can you tell me how to fix this? – Jack Nov 05 '14 at 01:28
  • @Jack Ok, I added a lot more info – Michael Berkowski Nov 05 '14 at 01:49
  • Michael, my main page is actually going to have a text box & id input will be taken from that text box & upon clicking submit, I need to generate random string & using that string & my id from text box, I need to generate QR code on the same page. – Jack Nov 05 '14 at 01:57
  • @Jack This should work that way. Your main PHP page's `$_POST` handling should stay the same. It still generates the myid from $_POST, but in turn passes that value to the other QR code script via its query string. – Michael Berkowski Nov 05 '14 at 01:58
  • ...Added the modified main script above to illustrate. – Michael Berkowski Nov 05 '14 at 02:02
  • ok..so I need to keep my code as it is & only replace Qrcode related stuff with the img tag that you posted. And create another file generate_qrcode.php which will have code as you mentioned. But in that file, can I have function at the top for generaterandomcode? – Jack Nov 05 '14 at 02:02
  • One more question: Is there a way to put try catch for QRcode::png() line? I mean if QR code generation is successful, then I need to perform certain action. – Jack Nov 05 '14 at 02:40