How can I pull a random image from MySQL with PHP? - php

I'm learning PHP/MySQL while working on a web app. Part of this app calls for echoing out a random image from an image directory titled 'htdocs/full'. The database is holding the path to each image in a column titled 'image_path' in addition to columns for 'first_name' 'last_name'.
I'm able to make it call a random row from the database and I can make it display literal data from the 'first_name' and 'last_name' columns. But I'm struggling to make it take the path from the 'image_path' column and converting it into an image rather than a literal.
I've been experimenting with a number of methods over the last 24 hours, but most everything else I've been seeing on Stack and Google is for pulling an image straight out of the directory without using the database row (which is needed due to the corresponding 'first_name' and 'last_name').
Here is what I have so far (although I also have many different variations, this I think is the closest I've come):
<?php
$username="root";$password="*********";$database="offenders";
mysql_connect('localhost',$username,$password);
mysql_select_db($database) or die( "Unable to select database");
$sSQLQuery = "SELECT image_path FROM offenders ORDER BY RAND() LIMIT 1";
$aResult = mysql_query($sSQLQuery);
WHILE($aRow = mysql_fetch_array($aResult)):
{
header("Content-Type:image/jpeg");
echo "<img src='php/imgView.php?imgId=".$aRow['image_path']."' />";
}
ENDWHILE;
?>
It produces a page with a tiny broken image at the top left. I've tried this with echoing $aRow as well as $aRow['image_path'] as seen above and a number of other tweaks that seems to cause error. Any ideas what I'm doing wrong?
Thanks a lot!
Updated code:
<?php
$username="root";$password="*******";$database="offenders";
mysql_connect('localhost',$username,$password);
mysql_select_db($database) or die( "Unable to select database");
$src="full/";
//if you have any problem in the solution check this line,
//means weather you are providing right path for your files or not.
$sSQLQuery = "SELECT image_path FROM offenders ORDER BY RAND() LIMIT 1";
$aResult = mysql_query($sSQLQuery);
$aRow = mysql_fetch_array($aResult);
$file_path=$src.$aRow["image_path"];
//echo "<a href='php/imgView.php?imgId=".$aRow['image_path']."'>"."<img src=".$file_path." />"."</a>".'<br/>';
echo "<img src=".$file_path." />".'<br/>';
//echo "<img src=full/1b2ba2f9a8b8ee9c062b09767535d69bd954e125.jpg>";
/* if(isset($_GET['imgId']))
{
//i am query only first_name but you can add for field as you want
//and i also used $_get['imgId']; in the query which is not safe but you can make it for //secure.
$sSQLQuery = "SELECT first_name FROM offenders where image_path='".$_GET['imgId']."'";
$aResult = mysql_query($sSQLQuery);
WHILE($aRow = mysql_fetch_array($aResult)):
{
echo $aRow['first_name'];
}
ENDWHILE;
}
*/
?>

There are several things wrong here.
You have your database output in a loop. Instead of
WHILE($aRow = mysql_fetch_array($aResult)):
{
...
}
ENDWHILE;
use:
$aRow = mysql_fetch_array($aResult);
...
You are returning what looks like HTML, but you have a content type of JPG. Either return HTML and use an appropriate content type or return a JPG, and return that.
If you want to return the JPG itself (and not the HTML), use CURL to grab the write image and return it.

In my view i dont know why you are running the while loop because in your query you have limit of one so you dont have to run the while loop.
lets say you have your images in the folder name php/image/than your images comes
I am writing my solution on the assumption that your images are in the image folder, if they are not you can simply change the $src value in the solution.
and i am also thinking you want to use these images as a link, so you can get the first_name, and last_name when some one click on the image, reason i am thinking like this, that you try to give id in the img src="",
any way i am writing two solution see which one work for you. first one gonna make them link and second one only gonna pull the images from the database.
First one on the assumption you want to pull the first_name and last_name, from the database, when some one click on the image.
<?php
$username="root";$password="";$database="offenders";
mysql_connect('localhost',$username,$password);
mysql_se
lect_db($database) or die( "Unable to select database");
$src="php/image/";//if you have any problem in the solution check this line,
//means weather you are providing right path for your files or not.
$sSQLQuery = "SELECT image_path FROM offenders ORDER BY RAND() LIMIT 1";
$aResult = mysql_query($sSQLQuery);
$aRow = mysql_fetch_array($aResult);
$file_path=$src.$aRow["image_path"];
echo "<a href='php/imgView.php?imgId=".$aRow['image_path']."'>"."<img src=".$file_path." />"."</a>".'<br/>';
if(isset($_GET['imgId']))
{
//i am query only first_name but you can add for field as you want
//and i also used $_get['imgId']; in the query which is not safe but you can make it for //secure.
$sSQLQuery = "SELECT first_name FROM offenders where image_path='".$_GET['imgId']."'";
$aResult = mysql_query($sSQLQuery);
WHILE($aRow = mysql_fetch_array($aResult)):
{
echo $aRow['first_name'];
}
ENDWHILE;
}
?>
Second solution only pull the images from the database
remove the isset condition and while loop in the isset condition.
and change this line
echo "<a href='php/imgView.php?imgId=".$aRow['image_path']."'>"."<img src=".$file_path." />"."</a>".'<br/>';
To
echo "<img src=".$file_path." />".'<br/>';
//if you notice the only different is this that i
//remove the <a> tag in its path, so not it gonna pull images
// from the database but you cant use them as link.
Thanks
this solution work fine if it does not please post your folder structure, means where you have images and this file imgView. and second note i removed your while loop from the solution,
//

Related

What PHP do I need to insert into this mysqli_fetch_array to ensure NULL urls aren't used?

I have a webpage which uses php to pull through data from a MySQL database. The database stores my writing portfolio organised by columns date, url, category, title, publication, description. It pulls through the title and publication and uses the url to turn it into a hyperlink (see code below). So far, so good.
Where I'm stuck: Sometimes there's no url for something I've published (e.g. for a few of the 'Content & Copywriting' items on my site), but it still turns my title and publication into a link: a link to "_blank". When there is a NULL url, I need it to not turn my title into a link at all.
So, I think I need to insert some sort of logic so that if url=NULL, then it doesn't make the text into a link, instead of creating a link to "_blank". But this is completely beyond my capabilities right now - I don't know where to even start !
I hope that all makes sense. Any guidance/pointers in the right direction welcome! And please let me know if anything's not clear.
<?php
$query = mysqli_query($dbconnect, "SELECT * FROM main WHERE category = 'Content & copywriting' ORDER BY date DESC")
or die (mysqli_error($dbconnect));
while ($row = mysqli_fetch_array($query)) {
echo "<a href=$row[url] target='_blank'>$row[publication] - $row[title]</a><br>";
echo "$row[description]<br><br>";
}
?>
try check for empty values
while ($row = mysqli_fetch_array($query)) {
if( !empty( $row['url'])){
echo "<a href=$row[url] target='_blank'>$row[publication] - $row[title]</a><br>";
}
echo "$row[description]<br><br>";
}

PHP/MySQL: Limit foreach loop when more than one occurance is found

I'm new to PHP and MySQL and I'm currently making a blog portal. On the index page, all recent posts are shown with the title, author, date, the first 150 characters of the post plus an image from the post.
I have two tables in MySQL: "post" and "image" and I'm looping through both of these with foreach to check if a post has an image connected to it with the same postId. My problem is if a post has more than one image, I only want one image to show and not all of them like it does now. I tried making a query selecting all posts from a user where post.id = image.postId, but then the posts with no images were not shown.
I appreciate any input or suggestion on how to make this work, or maybe an entirely different approach.
In PHP/HTML file (removed the part of the code in the loop where title/content and so on is added):
<?php foreach($allPosts as $key => $onePost): ?>
<?php foreach($allImages as $one => $oneImage): ?>
<?php if ($oneImage['postId'] === $onePost['id']): ?>
<?php echo '<img src="../Images/' . $oneImage['filename'] . $secondString; ?>
<?php endif; ?>
<?php endforeach;?>
<?php endforeach;?>
In PHP/database file:
function selectAllPosts($conn)
{
$sql = '
SELECT p.*
, u.username
FROM post p
JOIN users u
ON p.userId = u.id
ORDER
BY created DESC
';
return $allPosts = db_select($conn, $sql);
}
function selectAllImages($conn)
{
$sql = 'SELECT * FROM image';
return $postImages = db_select($conn, $sql);
}
You can limit your image query by adding a 'where' and a 'limit'.
something like this could work:
'SELECT * FROM image WHERE image.postId=post.id LIMIT 1'
This approach assumes that every image has the attribute 'postId', which is the id of the post, which contains the image
Note: With this query, it is undefined which iamge you get after the limit. In practice it's mostly the image which is saved first in the db, but it can vary. If you want to get a specific image, you can either add some boolean column to the imagetable e.g. 'hero-image' and use this query
'SELECT * FROM image WHERE image.postId=post.id AND image.hero=true LIMIT 1'
OK I firstly suggest for the sake of security that you use PDO in your connections to your dbase (see https://www.udemy.com/course/php7-beginners-guide-to-database-pdo/.
A simple way to get only one image from the dbase is:
$sql = 'SELECT * FROM image LIMIT 1';
How is your image table structured? Are you fussy which image is displayed? If so, when loading a record you could have one field for preferred image location and another or others for the rest, you can then select your image from the preferred image field if one exists.
Alternatively you can store the image locations in an array and only choose the first one in the array (see: https://www.php.net/manual/en/function.mysql-fetch-array.php)
As some records do not have image locations in them you will also need to include a filter in the display code like:
if(empty($row['image'])){
}
else{
echo 'Your image display code Here';
}

URL and link text from database

I am currently still learning PHP so some things I still struggle with.
I have been taking it slowly and reading tutorials which has helped but I can't figure this one out.
I have a database table (in mysql) with let's say, 100 urls. There is a column called 'url' and a second column 'text'. I already have the pagination code which works, so will also be using that.
What I want to do is echo out the URLs (which are all in folder called blog in the root of my site), but use the text as the link.
So for example the first three rows in my table might be:
url
001.php
002.php
003.php
text
random text
some random text
more text
when echoed out the links show the text from the column text like:
random text
some random text
more text
and will open to the relevant url when clicked
I'm guessing it will need some kind of loop to collect all the URLs and save me adding the link text in manually, and then my pagination code will split them up.
This is my first time asking a question on here, so if it wasn't clear enough or you need more info, let me know.
I have done multiple searches on the internet but can't seem to find a tutorial.
Assuming you connect to a local mysql server with username "root" and password "root", and have your url's stored in a table named url_table in a database named url_database you could do something like:
$connection = mysql_connect("127.0.0.1","root","root"); // Connect to the mysql server
mysql_select_db("url_database"); // Open the desired database
$query = "SELECT url,text FROM url_table"; // Query to select the fields in each row
$result = mysql_query($query); // Run the query and store the result in $result
while($row = mysql_fetch_assoc($result)) // While there are still rows, create an array of each
{
echo "<a href='".$row['url']."'>".$row['text']."</a>"; // Write an anchor with the url as href, and text as value/content
}
mysql_close($connection); // close the previously opened connection to the database
What you need is to:
get your result array from the database. Use something like
$query = "SELECT * FROM urls";
$result = mysql_query($query);
For every row in your results table, show the corresponding url. Note that calling mysql_fetch_array on a result resource, returns the first row of the results table when called for the first time, the second on second time etc. The function returns false when there are no more rows to return.
(See more on that in the mysql_fetch_array() documentation)
While( $row = mysql_fetch_array($result) ){
echo '<a href='.$row['url'].'>'.$row['text'].'</a>';
}
Here is a sample you can start with:
$con = mysql_connect("host","user","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("my_db", $con);
$result = mysql_query("SELECT the_url, the_text FROM my_table");
while($row = mysql_fetch_array($result))
{
echo '"' . $row['the_text'] . ' <br />';
}
mysql_close($con);
First, you want to select only the relevant lines in your database for the page that the user is currently viewing. For example, if the user is viewing page 2, with entries 15-30 present, we only want to pull those entries from the database. This is an efficiency concern.
The code you're after is something like this:
$link = mysql_connect(/*connection parameters go here*/);
if ($link === false)
die;
mysql_select_db('my_database');
$result = mysql_query("SELECT text, url FROM my_table LIMIT 15,30");
print "<ul>\n";
while ($row = mysql_fetch_assoc($result)) {
print "<li>{$row['text']}</li>\n";
}
print "</ul>\n";
mysql_close();
The first three lines establish a connection to the database, and exit the script if an error occurs.
The next line selects the appropriate database on the server.
The next block runs the appropriate query for the second page. After the query is run, a 'result' is stored in $result. This result is comprised of a number of rows, and mysql_fetch_assoc($result) obtains those lines one at a time. It then formats these lines into the appropriate link format and outputs them. The entire set of links is wrapped in a dot-point list.
Finally, mysql_close() closes the connection to the database.
I'm assuming since you just started you're probably doing all this procedurally.
First you want to query the database and get the info you need.
<?php
$result = mysqli_query($link, "SELECT url, text FROM table_name");
while ($row = mysqli_fetch_array($result)) $hrefs[] = $row;
foreach ($hrefs as $href) {
echo "".$href['text']."";
}
?>
Please note I've done no error handling here.

Reading from mysql table issue

I'm dealing with strange problem.
$result = mysql_query("SELECT link FROM item WHERE item_id='$id2'") or die(mysql_error());
$row = mysql_fetch_assoc($result);
$picture = ''.$row['link'].'';
echo"$picture";
Gives me result http://127.0.0.1/1321426277. without ending, while in column link link is: http://127.0.0.1/1321426277.jpg. Why it cuts ending?
For testing purposes please run
$result = mysql_query("SELECT link, Length(link) as l FROM item WHERE item_id='$id2'") or die(mysql_error());
$row = mysql_fetch_assoc($result);
if ( !$row ) {
echo 'no such record';
}
else {
$l = strlen($row['link']);
var_dump($l, $row['l'], $row['link']);
$picture = $row['link'];
echo "'$picture'";
}
and post the result.
I don't see anything in your code that would cause the link to be truncated. Have you checked to make sure you have the correct data in your table?
It looks like a bug in the data. Print out (and select) the ID at both places (the query in your question and the other place where you use it in img src tag). I bet they will differ. Or, you should check SELECT count(1) FROM item WHERE item_id='xxx'*, where xxx is the ID of the magic record.
Ah now I see = the problem is because you code contains an 'r' after the 'o' rather then before - it is so clear now because you provided such a complete example of the behavior that I replicate on my machine.
WTF

Save image URLs in MySQL?

I actually have a few questions here: My end goal is to write a script that will automatically display all the images that i have saved inside my database(If i add new images to my database(image URLs), each time i refresh the page i would like those "new" images to be instantly displayed as well).
What is the proper way to save an image URL inside MySQL? Currently i set my input type to VARCHAR; is that okay for image URLs?
Also, at the moment i'm working with WAMP server just to test how the site is working; so i put an image inside the www folder(within the same folder as my php script) and inside the database table i simply put the URL as follows: image.png is this the correct way to enter an image URL inside my database?
What is the best way to display these images in a sequence? The following code is what i have so far:(the image widths will take up about 70% of the page so the images will not be next to each other; they will be in a column form.)
<?php
$db_host="host";
$db_user="user";
$db_pass="pass";
$db_name="name";
$db_table="table";
mysql_connect($db_host, $db_user, $db_pass) or die(mysql_error());
mysql_select_db($db_name) or die(mysql_error());
$query = mysql_query("SELECT * FROM tablename");
$result = mysql_query($query);
$num = mysql_num_rows($result);
for($count = 0; $count < $num; $count++)
{
//output the rows one by one(the actual images, not the URLs)
mysql_fetch_row($result);
echo("<br/>");
}
?>
I don't know if i should be using mysql_fetch_row in there..
I want my images to have some space in between; i was thinking the best way to accomplish that would be to add a "br" tag at the end of my loop so that every time a new image is displayed, a line break will be added to the end of the page.. Is that the best way to do it?
Thanks a bunch in advance!
To your first question, yes. To your second, also yes, if all your images are stored in the same directory. Mostly it's a matter of preference though.
Your for loop should look like this:
for($count = 0; $count < $num; $count++) {
$row = mysql_fetch_assoc($result);
echo "<img src='". htmlspecialchars($row["image"]) ."' alt='image' />";
}
br tags would probably be a bad idea. Set the images' display property to block in your CSS file. There are plenty of CSS manuals online.
With
$query = mysql_query("SELECT * FROM tablename");
$result = mysql_query($query);
$num = mysql_num_rows($result);
you do some things twice. You do not want $query to be the result of a mysql_query() call and then apply mysql_query() again.
In this case, the second call would happen with a resource object instead of a string - you got informed about it. By putting "" around, you turn it into a string again, but one which doesn't make sense to mysql.
To verify that, try to put or die(mysql_error()) to the problematic calls.
And to fix that, you can try
$query = "SELECT * FROM tablename";
$result = mysql_query($query) or die(mysql_error());
$num = mysql_num_rows($result);
BTW: you don't need $num when you replace the for loop with
while ($row = mysql_fetch_row($result))
// do stuff with $row
}
I've done a previous project based on image storage in a SQL database. the best way to store the images would be as a link, ie, '/stored_images/imagefilename.png'. When you need to reference the images just get the images into a while loop for each row in the table.
ie.
to get the images
<?php
$query = mysql_query("SELECT * FROM tablename");
while ($row = mysql_fetch_array($query)) {
echo '<img src="' . $row['column of url storage in SQL'] . '" />';
}
That will output all the images in the database, just change 'column of url storage in SQL' with the actual column name that you store in the SQL DB. also replace 'tablename' in the SQL query with the name of the table the images are being stored in.

Categories