I am retrieving an array of book objects with attributes like title,isbn and image. When I wish to display only labels using for loop it is displaying all entries. But when I try to display image, it only displays one. Also when I try to display both title and image, it says can
Warning: Cannot modify header information - headers already sent by (output started at /Applications/XAMPP/xamppfiles/htdocs/BookStore/BooksResult.php:14) in /Applications/XAMPP/xamppfiles/htdocs/BookStore/BooksResult.php on line 15.
Below is the code.
foreach($booksArr as &$book)
{
$content = $book->Image;
$title=$book->s_Title;
echo $title;
header('Content-type: image/jpg');
{
echo $content;
}
}
The "Cannot modify header information..." problem is here:
header('Content-type: image/jpg');
Your PHP script is outputting HTML. You cannot change the content type of the output mid-stream. Instead, you should output an <img> tag that points to the image location.
UPDATE BASED ON COMMENT DATA:
If you need to serve your images as blobs from the database, you will need to create a separate script to fetch the images. First modify this one to reference the new script by creating an <img> tag with a src attribute that contains the path to your image-fetching script and the image ID:
<img src="/path/to/your/new/script.php?id=<?php echo $row_id; ?>" />
Substitute $row_id with the field data that uniquely identifies a book in your database.
Next, create the new image fetching script. It will contain three elements:
A line to get the id from the GET request:
$id = $_GET['id'];
An SQL statement to fetch the image blob based on the ID. (Remember to sanitize your input!)
A header() statement like the one you used in your original script
After the header() line, just output the blob, and your image will be displayed.
Try adding
ob_start()
At the beggining of the file
EDIT: Also, only modify the header information once, just call the header function once at the beggining of the file, after ob_start()
Headers may only be sent before any output is sent. You are echoing the title and then try to set the headers.
You are trying to send all the photos in one request. HTML doesn't work like that. You need to do something like this:
foreach($booksArr as &$book) {
$title=$book->s_Title;
echo $title;
echo '<img src="book_image.php?id=' . $book->id . '" alt="' . $title . '"/>';
}
and then handle the books in a separate request on book_image.php, where you would print out the appropriate header and content, something like this:
$id = $_GET['id'];
// get the book by id from db
header('Content-type: image/jpg');
echo $book->Image;
If you really want to understand this warning, and you want to work more with PHP in the future then you should start to learn how the HTTP protocol works. Its fun, and you will see much more clearly after:)
(this is just a general advice, not the exact answer to your question)
Related
okay so it is appearing to me my header() isn't doing anything. i tried moving it to the very top of the file instead nothing changed unless I put it in its own but then the rest of the file doesn't run but it does send the header.
EDIT: I updated my code with your suggestions, but it still isn't working correctly. Below is an image of the network tab when I inspect the page. The big thing I notice is the calls are being made but its fetching the same about of data for every image and its a very tiny amount of data.
edit: I am getting and Invalid URL Error when I inspect in chrome unless I remove data:image/png;base64,
Referrer Policy: strict-origin-when-cross-origin
I can't seem to get this working correctly. The png image should be pulling from the database and then displaying in the HTML. (and yes I know this isn't SQL injection safe) I assume there is some issue with it being called from the loop, but I am unsure. Or that it can't find the getImage.php to use it this way do i need to import it or something earlier in the code? It does correctly pull in the item_id. The result just gives me a broken image box. I know my getImage.php is outputting the correctly formatted image, because I have taken the output directly from there and inserted in place of the call for it and the image has show up. So it tells me this line below is my issue
echo ('<td><img src='"getImage.php?image_id="' . $row["item_id"].'"></td><td>');
if I edit as follows it works fine (but obviously it give me the same image for every entry) DBS is the decoded byte string that getImage.php outputs
echo ('<td><img src="data:image/png;base64,DBS"></td><td>');
PHP for the Front Facing page (blackmarket.php:
$sql="SELECT * FROM `item` WHERE 1";
$result = $link->query($sql);
echo("<table>");
if ($result->num_rows > 0) {
// output data of each row
echo("<tr>");
while($row = $result->fetch_assoc()) {
$newrow=0;
echo("<td>");
echo ('<img src="getImage.php?image_id='.$row['item_id'].'" />');
getImage.php:
<?php
require_once "connect.php";
if(isset($_GET['item_id'])) {
$sql = "SELECT item_img FROM item WHERE item_id=" . $_GET['item_id'];
$result = mysqli_query($link, $sql) or die("<b>Error:</b> I can't find the image <br/>" . mysqli_error($link));
$row = mysqli_fetch_array($result);
header("Content-type: image/png");
header("Content-Length: " . strlen($row["item_img"]));
echo $row["item_img"];
}
mysqli_close($link);
Just specify
echo "<td><img src=\"getImage.php?image_id={$row['item_id']}\"></td>";
The browser is responsible for assembling the page, and makes a separate call to the getImage.php script and reads the image data that you are returning.
Return the binary image data directly, along with the size. This might also be part of the problem.
<?php
require_once "connect.php";
if(isset($_GET['item_id'])) {
$sql = "SELECT item_img FROM item WHERE item_id=" . $_GET['item_id'];
$result = mysqli_query($link, $sql) or die("<b>Error:</b> I can't find the image <br/>" . mysqli_error($link));
$row = mysqli_fetch_array($result);
header("Content-type: image/png");
header("Content-Length: " . strlen($row['item_img']));
echo $row['item_img'];
}
mysqli_close($link);
Omit the closing php end tag ?> from this script. PHP best practices is to omit it for all scripts but it is especially important in a script like this that returns binary data, as a bit of whitespace or a UTF-8 BOM character can corrupt your output and is often hard to debug.
You are confusing two things:
data: URIs allow you to embed an image directly in the source code of an HTML page, so that the browser can render them immediately without another call to the server. They use base64 to make the data consist only of text, because you can't put non-text characters in the middle of your HTML source code
Normal https: URLs tell the browser to make a request to the server, which returns the image data, with no extra encoding needed. Most commonly, the web server will load the image straight from disk, but the browser doesn't know about that, so you can just as validly have a PHP script which returns the same data, based on whatever logic you want.
In your code, you've mixed the two: you've prefixed a normal URL with data:, so the browser is expecting the data right there in the source code, and never makes a call to getImage.php.
What you need to do instead is make sure that in your getImage.php you
echo out just the image data - no whitespace or debug output mixed in
not base64 encoded (if it's stored in the database that way, decode it before sending to the browser)
tell the browser it's an image with an appropriate Content-Type header, e.g. header('Content-Type: image/png'); - again, no mention of base64 encoding or anything else, you're serving an image just as if it was a file on your server
You shouldn't need to set the Content-Length header manually, the server will sort that out just like it would if you were outputting HTML
You can then load that image URL directly in the browser and it should display, no need to even look at your HTML until that part is working right.
Well I finally figured out what was going wrong. In my connect.php I had some white space and that white space was being called before my header so my header wouldn't work
The code works fine if i display only image with the help of code.
<?php
// my code processing
header("Content-type: image/png");
imagepng($base_image);
?>
But if i use some other fields like echo some text or i want to put some buttons on my page.
I get error, for code:
<?php
echo "hi";
?>
<?php
// my code processing
header("Content-type: image/png");
imagepng($base_image);
?>
It gives me error : The displayed page contains some errors.
Can someone please help me in this regard.
Any output before the Content-Type header will break your code. The browser does not know you are trying to serve it an image since it will have already defaulted to text/html by the time your image data turns up. If you want an image at a given point in your page, you will need to serve it as a separate object. The easiest way is to wrap it in an <img> tag e.g. <img src="myimage_generator.php" />
This answer is based off of another SO answer. Your problem is that you're trying to send header info after you already sent data to the browser, which is not possible. Even so you can't display an image on a page with it's data alone. You need to base64 encode the image data first. This way you can build a whole HTML page and place this image anywhere on it and position it with CSS.
// Enable output buffering
ob_start();
imagepng($base_image);
// Capture the output
$imagedata = ob_get_contents();
// Clear the output buffer
ob_end_clean();
echo '<img src="data:image/png;base64,'.base64_encode($imagedata).'">';
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
$sql="SELECT * FROM `blob` ";
$query=mysql_query($sql);
while($row=mysql_fetch_array($query)) {
$image=$row ['image'];
header("content-type: image/jpg");
echo '<img src="path/'.$image.'" width="360" height="150">';
}
This is the code i'm using to display the image uploaded to my database... however, i get the error message that the headers have already been sent... i have no idea what i'm doing wrong!
i can see on my website where my images are meant to be but no actual image!
In general:
When you get this message it seems that there is an output done before. It can even be a simple "whitespace" character like [:space:].
But:
In addition to that you seem to get some things wrong. You do create HTML (!) but you send a header-message that tells the browser that it get's binary data of an image.
So when you really have binary data in your database you have to output binary data and not any html "thingy". I really really recommend you to read a good book about how a server works and what header(..) actually does.
Please also have a look here:
php:Store image into Mysql blob, Good or bad?
http://pujanpiya.com.np/?q=node/25
PS: I did not get into any more detail about your question neither provide a solution because I do not think this would help you rather than solving this issue of misunderstanding temporarily.
Your code is totally wrong; storing images inside a MySQL database is a bad idea and you're using your image data as a path to a nonexistent image; if you still want to stick with the idea of having images in your database, here's example code that would work :
while ($row = mysql_fetch_array($query)) {
echo '<img src="data:image/jpeg;base64,'.base64_encode($row["image"]).'" />';
}
This encodes the image into base64 and then uses that as a data URI inside an img; no headers needed.
Also, mysql is deprecated; use mysqli or PDO instead.
The problem is that you're doing it in a while loop, which will be executed multiple times:
while($row=mysql_fetch_array($query)) {
$image=$row ['image'];
header("content-type: image/jpg"); // Headers are sent here
echo '<img src="path/'.$image.'" width="360" height="150">'; // Content here
}
When mixing headers like this, what you would normally want to do is put the header before any content. However in your case, this wouldn't make sense either because you are sending "content-type: image/jpg". If you are echoing an image to the browser using HTML, the content-type should be text/html (which is sent by PHP by default). So just leave that line out completely. If you are trying to send the actual binary contents of an image, then you wouldn't use an HTML tag, just send the Content-Type header and then echo the contents for one single image.
Let's say I have a user enter the URL of an image.
After URL validation, etc. I want to get the image and store it in a PHP variable. Not the image path, but the actual image itself.
I am adding this image-holding variable in between other strings, so I cannot change use header() before echoing the image. Is it possible to use <img> HTML tags? I really don't want to copy the images to my own server...
How do I:
Store the image in a variable such that,
Echo the image from the variable without changing headers.
Edit:
I said above that I am putting this image inside another variable, e.g.:
$str = "blah blah" . $var_holding_img . "more text";
Is it possible to insert something in the string above that will be replaced with the images? Can parse the variable $str later to replace some random text like "abg30j-as" with the image...
I found an answer to my own question:
First, I created another PHP file, called img.php:
<?php
$url = $_GET['imgurl'];
/*
Conduct image verification, etc.
*/
$img_ext = get_ext($url); //Create function "get_ext()" that gets file extension
header('Content-type: image/' . $img_ext);
echo file_get_contents($url);
?>
Then, in the original PHP file, I used this PHP code:
<?php
$var_holding_img = '<img src="img.php?imgurl=http://example.com/image.png"/>';
$string = "This is an image:<br \>" . $var_holding_img . "<br \>displayed dynamically with PHP.";
echo $string;
?>
This way, the PHP file "img.php" can use the proper headers and the image can be inserted as HTML into any other PHP variable.
How do I:
Store the image in a variable such that,
Echo the image from the variable without changing headers.
You can do this in two ways.
In way one, you serialize the image in a string, and save the string in the session. Which is exactly the same as saving it server side, except that now the session GC should take care of clearing it for you. Then the IMG SRC you use will redirect to a script that takes the image and outputs it as image with proper MIME type.
In way two, if the image is small enough, you can encode it as BASE64 and output it into a specially crafted IMG tag:
http://www.sweeting.org/mark/blog/2005/07/12/base64-encoded-images-embedded-in-html
This saves you some time in connection, also. Of course the image must be reasonably small.
You can't save the actual image in a variable. Either you save the URL or copy the image (what you obvious don't want) to your server and save the path to the image
See answer 1, you can't echo the image itself, only link it
Edit: Okay obviously you can save images directly to a variable, but I don't recommend you to do this.
No, that isn't possible. If you want to serve something, it has to exist on the server.
I need to send a GET request to my page pic.php, and I want to get a real picture in return.
For now I implemented this idea like this:
<?php
if ((isset($_GET['pic']))&&(isset($_GET['key']))){
$pic = $_GET['pic'];
$pic=stripslashes($pic);
header('Location: /content/'.$pic);
}
?>
But it's not really what I want - it redirects to image directly. What I want is to keep the same URL, but get a needed file depending on what values were submitted.
What is the best way to do that?
thx.
This example code snippet should do what you ask. I've also included code to only strip slashes if magic quotes is enabled on the server. This will make your code more portable, and compatible with future versions of PHP. I also added use of getimagesize() to detect the MIME type so that you output the proper headers for the image, and do not have to assume it is of a specific type.
<?php
if(isset($_GET['pic']))
{
//Only strip slashes if magic quotes is enabled.
$pic = (get_magic_quotes_gpc()) ? stripslashes($_GET['pic']) : $_GET['pic'];
//Change this to the correct path for your file on the server.
$pic = '/your/path/to/real/image/location/'.$pic;
//This will get info about the image, including the mime type.
//The function is called getimagesize(), which is misleading
//because it does much more than that.
$size = getimagesize($pic);
//Now that you know the mime type, include it in the header.
header('Content-type: '.$size['mime']);
//Read the image and send it directly to the output.
readfile($pic);
}
?>
I can see you doing this in two ways:
1) Return the URL to the image, and print out an image tag:
print '<img src=' . $img_url . ' />';
2) Alternatively, you could just pull the data for the image, and display it. For instance, set the header appropriately, and then just print the image data.
header("content-type: image/png");
print $img_data;
This assumes that you have the image data stored in a string $img_data. This method will also prevent you from displaying other things on the page. You can only display the image.
You can load the image, send the image headers, and display the image as such:
header('Content-Type: image/jpeg');
readfile('/path/to/content/pic.jpg');
Obviously the headers would depend on the filetype, but that's easy to make dynamic.
Not sure if I understand what you're after, but guessing that you want to load the picture in an img tag?
If I'm right you just do:
<img src=http://www.domain.com/pic.php?"<?php echo image here ?>" />
Basically you just make the source of the image the webpage you get directed to where the image is.