0

Good morning,

I have an issue with the rendering of my file output, it seems to show it as plain text which you can see at this link if you try typing and submitting it.

www.hiven.net/index.php

It seems as if the page is being rendered as plain text, but the only explanation I can see online is if I had set it to be plain text in my php header, which I haven't. Is it because I am setting the output content type to PNG, and if so, how can I make it render the image on a HTML page?

index.php

<?php
require_once('functions.php');
?>
<html>
<body>
<form action="/" method="post">
<input type="text" name="name">
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
<?php
if (isset($_POST['submit'])) {
  process();
}
?>

functions.php

<?php
function process()
{
/* Create some objects */
$image = new Imagick();
$draw = new ImagickDraw();
$pixel = new ImagickPixel( 'gray' );

/* New image */
$image->newImage(800, 75, $pixel);

/* Black text */
$draw->setFillColor('black');

/* Font properties */
$draw->setFont('Bookman-DemiItalic');
$draw->setFontSize( 30 );

/* Create text */
$image->annotateImage($draw, 10, 45, 0, $_POST["name"]);

/* Give image a format */
$image->setImageFormat('png');

/* Output the image with headers */
header('Content-type: image/png');
echo $image;
}
?>
Jimmy
  • 10,619
  • 22
  • 84
  • 170
  • Your link seems to be working fine. – BizzyBob Feb 23 '17 at 12:49
  • @Jimmy Working fine – sandip kakade Feb 23 '17 at 12:49
  • You are still outputting your HTML code before the image, which is of course wrong. – CBroe Feb 23 '17 at 12:50
  • You are telling the browser that (first) you're giving it a HTML type document, and then you're giving it a PNG type document. This document can not be both types at the same time. Display one or the other. Not both. – Martin Feb 23 '17 at 12:52
  • @Martin I thought that was the issue, but I don't want my entire page to be a PNG type, just the image that is generated. I'm not sure how to isolate the type to just the image. – Jimmy Feb 23 '17 at 12:55
  • @BizzyBob It's not my end, perhaps because im on IE – Jimmy Feb 23 '17 at 12:56

3 Answers3

2

@Martin I thought that was the issue, but I don't want my entire page to be a PNG type, just the image that is generated. I'm not sure how to isolate the type to just the image.

This IS the issue, you're telling the browser that your page (whatever.php) is a HTML file and then you're telling it that it's a PNG file. This is obviously incorrect as a file can not provide headers to be multiple types at the same time.

What is happening is this:

  • Server sends HTML data with headers stating something link Content-type: text/html
  • Server sends [static] HTML contents (which you display).
  • Server then sends the output of PHP process() function which is:
  • Header for PNG stating Content-type: image/png
  • Data contents for PNG file.

Can you see how this causes a clear issue that the browser is loading one output rather than another.

Solutions

  • 1) Just output the PNG, this will involve not sending HTML headers or HTML content (credit to User2342558).

    <?php
    require_once('functions.php');
    if (isset($_POST['submit'])) {
        process();
        exit;
    }
    <html>
    ...
    

Note the exit; which forces PHP to stop executing the page once the process function is done, so that once the PNG is output then no further output is provided to the browser. This means the browser will only see one file type contents and will not present an error.

but I don't want my entire page to be a PNG type,

You state you don't want the page to be just a PNG image, so another solution is here:

  • 2) Load the PNG as a seperate <img> file

pngfile.php

   require_once 'functions.php';  // Requires and includes do not need brackets.
   $inputData = urldecode($_GET['data']);
   process($inputData);
   exit;

whatever.php

    <?php 
    if (isset($_POST['submit'])) {
       $data = $_POST['name']; // the data from the form input.
    }
    ?>
    <html>
        <body>
        <form action="/" method="post">
        <input type="text" name="name">
        <input type="submit" name="submit" value="Submit">
        </form>
         <img src="pngfile.php?data=<?php print urlencode($data);?>"
              alt="png php file">
     </body>
     </html>

This will then reload the current page and pass the input form fields as URL values to the pngfile.php script which will run as if it is a PNG file, and nothing else.

This means your form page will load both the form and the image at the same time. And as these two files both have separate and distinct headers (one is text/html, the other is image/png this will not cause a browser problem.

  • 3) A third and probably more complex solution is to construct the image as an SVG codeblock and display it inline in the HTML page, this negates the need to provide headers but there may be various secondary issues.

    This would also need a fair bit of code adjustment for you current functions.

Finally

As ever with PHP, also keep an eye on your PHP error logs.


Process function Editing

You need to update the process function to accept and use the data value. your default process function is using script-global values ($_POST) but will need to use the values specified in process($data) part of your whatever.php because the image file (pngfile.php) will get nothing POSTed to it.

<?php
  function process($newData){  
  $image->annotateImage($draw, 10, 45, 0, $newData); //updated
        // To use the specified value passed into the function. 
  ... 
  header('Content-type: image/png');
  echo $image;
  exit; // should be return not exit here. 
}
?>
Community
  • 1
  • 1
Martin
  • 19,815
  • 6
  • 53
  • 104
  • I followed solution 2 because it seems like a really tidy solution but I can't get it working. This is the complete code set: https://gist.github.com/anonymous/9d721ab56e20fb943f495d1d5e46a7ba and this is the link www.hiven.net/index2.php - it just seems to draw a blank image? – Jimmy Feb 23 '17 at 13:28
  • 1
    @Jimmy ok take a look I've exampled pssing the data to the `process` function. – Martin Feb 23 '17 at 13:32
  • Ah I see, so I would do ```function process($data)``` and ```$image->annotateImage($draw, 10, 45, 0, $data);``` - That hasn't quite worked for me just yet but it gives me enough to investigate. Oh you have helped, thank you very much! – Jimmy Feb 23 '17 at 13:33
  • Yes that was just my fault copying in, it doesn't look like that on the server – Jimmy Feb 23 '17 at 13:36
  • @Jimmy if you're just copy pasting my answer, I've just seen that I had the wrong POST value, i had put `$_POST['text']` when the input *type* is text and it's name is *name*. Updated. – Martin Feb 23 '17 at 13:38
1

Try to put the code immediatly after require_once('functions.php');:

require_once('functions.php');
if (isset($_POST['submit'])) {
    process();
}

And then put a exit; after echo $image;:

echo $image;
exit;

That because the html code corrupts the source of the image you are trying to send to the browser.

user2342558
  • 3,737
  • 4
  • 20
  • 46
1

You need to put else condition for form display

<?php 
require_once('functions.php');
if (isset($_POST['submit'])) {
  process();

}
else{
?>
<html>
<body>
<form action="" method="post">
<input type="text" name="name">
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
<?php
} ?>
B. Desai
  • 16,092
  • 5
  • 22
  • 43