Store and handle MySQL Results - php

So, I'm learning PHP and MySQL, but I have run into a little problem here.
I do lack some information, so this will be very helpful to me =)
I do a query against my database, and get a result. This result is all my image files to be listed.
$fileSQL = $mysqli->query("
SELECT *
FROM content
WHERE projID=$projectID
");
So, if I want to list all my files as thumbnails on my page I do this:
<?php while($row = $fileSQL->fetch_assoc()){ ?>
<img src="assets/<?=$row['contentFull']?>" id="thumbImg"
onclick="document.getElementById('mainImage').src=this.src" width="110px" height="62px"/>
<?php } ?>
Now, this works fine, of course. It loops through all the rows while adding a for each of them.
However, I do have a main image too, where I need to show the first thumb in full (for this example I use contentFull both for thumbs and fullsize).
Now, how do I get the first row's contentFull, without making the while loop start from row nr.2?
And in general; what is the best way to do in these situations? Store the result to an array first, so I can access it easily, or what is the "normal" way of doing it? =)
What I need:
Do a query
Set the main image (using contentFull from the first
image/content in my sql result)
Then draw all the images in the
result to thumbnails (including the first that are already shown as
the main image)
Thanks in advance, and please let me know if you need more information =)

One simple options would be to do this:
<?php
$first = null;
while($row = $fileSQL->fetch_assoc()) {
if(!isset($first)) $first = $row;
?>
<img src="assets/<?=$row['contentFull']?>" id="thumbImg"
onclick="document.getElementById('mainImage').src=this.src" width="110px" height="62px"/>
<?php } ?>
Now you have the first row stored in a variable to use, without having to store all the results in an array. If for some reason you want all rows stored in an array you could simply do this:
<?php
$rows = array();
while($row = $fileSQL->fetch_assoc()) {
$rows[] = $row;
//rest of code
}
?>
Then you could access first row by referencing $rows[0]
Another option would be to not use php to populate the full image. Instead use a javascript call to populate the first image.

I think you could take your first picture outside the while loop:
$row = $fileSQL->fetch_assoc(); // the first picture
if($row){
// show first image if it exists
}
while ( $row = $fileSQL->fetch_assoc()) // etc.
Probably code for larger image is different than for others, so it could be reasonable. If not, consider defining a function, or use a counter (or flag like in Pitchinnate's answer).

Related

Better understanding on how to pass variables

I have created a website which gets data from two 'different' MySql database tables. The tables have identical layouts (so the numbers in each table differs but 100% similar in ID's and column names). Now I am a complete self-made programming noob so bear with me in the following.
On the websites front page I display some data from both of the two tables. The way I do this is by creating a variable ($tableName) that holds the name of the table I need. This variable is then used for generating the necessary data in another file (data.php) and then displaying that data on the front page by the file design.php. This process is replicated for all tables in the MySql database. (below is a very simplified format).
Frontpage.php:
<?php
include('../connection.php');
?>
<?php
$tableName = table1;
include('../Data.php');
include('../Design.php');
?>
<?php
$tableName = table2;
include('../Data.php');
include('../Design.php');
?>
.....(etc.)
Data.php:
$query = "SELECT * FROM {$tableName} WHERE ID = 1";
$result = mysqli_query($conn, $query) or die('error');
while($data = mysqli_fetch_array($result)) {
For ($n = 0; $n < 1; $n++){
$dataVariable = $data["columnname"];
}
}
Design.php
<?php echo $dataVariable; ?>
So what happens is that the user goes to the $dataVariable link and is then sent to Ultimate.php which also includes the Data.php file in order to display a hell-uv-alot of data. I therefore have to again declare the $tableName variable in the Ultimate.php file and then duplicate the Ultimate.php file for every single table there is in the MySql database and change href-link in the Design.php file. (very annoying).
My question is: how can I pass on my $tableName variable from the href on the front page to Ultimate.php? I have searched on here and found a way which includes $tableName to the URL opened on Ultimate.php whereafter I use $_GET inside Ultimate.php to collect it. For some reason I couldn't make that work - and i don't know if this is at all a solid way to solve things in my case.
More importantly: I have never worked with programming before so if anyone can advise me whether I am setting this up most efficiently or not that would also be great! I very much welcome links to guides/tutorials which you think might benefit me at this point!
Thanks a lot in advance!
<?php echo $dataVariable; ?>
Then at the top of Ultimate.php:
<?php
$var = $_GET['var'];
?>
This takes the variable off the browser
http://www.example.com/Ultimate.php?var=yourvariable
You can pass variables from a hyperlink to another page using GET.
hyperlink text
$_GET['key']
http://php.net/manual/en/reserved.variables.get.php#refsect1-reserved.variables.get-examples

Mysqli Retrieve data and display them - best way

Which one of the options below is better
Option 1:
//control file:
$smpt = $con->query("SELECT id,name FROM customers");
//fetch all resuts
$results = array();
while ($row = $result->fetch_assoc()) {
$results[] = $row;
}
$smpt->close();
//Note: PHP version < 5.3.0 so I can't use just $results->fetch_all('MYSQLI_ASSOC');
//view file:
foreach($results as $key=>$value) {
//display results
}
unset($results);
Option 2:
//control file:
$smpt = $con->query("SELECT id,name FROM customers");
//fetch all resluts
//view file:
while($row = $result->fetch_assoc()) {
//display results
}
$smpt->close();
I am trying to completely separate the logic from presentation... Current I am using option 2 because with option 1 the script go through 2 loops. one to fetch data and the other to display them. But which one is better to use?
Thanks
Option 1 allows you to re-use the $data variable so you can display the results twice, but the cost of this is that you potentially have a large amount of data stored in a variable. You can clear this by using unset($data) once you are 100% sure you've finished with it.
Option 2 requires less loops (only one instead of two) and doesn't need a extra variable to store the data. The cost of this is that the while loop can only be used once.
In the grand scheme of things, the differences in speed will be so minimal the user won't notice them, however if there are 20+ instances of this in once script then it could have a noticeable affect.
I would recommend Option 2 providing that you'd only need to use the while loop once. Also, you could benchmark your scripts to see how they perform against one another.
It's always best that views only deal with presentation concerns.
So between the two options you've mentioned, I'd choose option 1 so you don't have to close $smpt inside the view ($smpt has nothing to do with the presentation layer).

Calling images dynamicly using javascript and php

i am new to Javascript and i have created the code below it works fine no problem at all however i want to know what is i want to pull the image dynamically using php and javascript from mysql database how can i refactor my code bellow. thanks in advance for your contribution.
var myimage = document.getelementById("mainImage");
var imageArray =["images/overlook.jpg","images/garden.jpg","images/park.jpg"];
var imageIndex =0;
function changeimage(){
myimage.setAttribute("src",imageArray[imageIndex]);
imageIndex++;
if(imageIndex >= imageArray.length){
imageIndex = 0;
}
setInterval(changeimage, 5000);
One of several options.
Query the database for the column with the URL of the images.
$query = mysql_query("SELECT url FROM images");
Then something like this to get an array out of it:
$images = array();
while($row = mysql_fetch_array($query)){
$images[] = $row['url'];
}
Then generate this string (that you use in the Javascript provided):
var imageArray = ["images/overlook.jpg","images/garden.jpg","images/park.
using the array you retrieved from the database. You could use json_encode in PHP for this if you don't want to mess around with error prone string building.
$imagesAsJsonArray = json_encode($images);
Echo it. Done.
Not the most elegant of solutions. But it gives you something to play with. Check out a few PHP tutorials online and you'll soon get the hang of it.
Two choices:
Using PHP when your page is created, put an array of images in the page and use page-level javascript to cycle among them.
Using Ajax in the page, call from the page to the server to get the next image and then use client-side javascript to make that returned image visible on the page.

PHPFlickr script...could this be cleaner/leaner?

OK, here's my dilemma:
I've read all over about how many guys want to be able to display a set of images from Flickr using PHPFlickr, but lament on how the API for PhotoSets does not put individual photo descriptions. Some have tried to set up their PHP so it will pull the description on each photo as the script assembles the gallery on the page. However, the method has shown how slow and inefficient it can be.
I caught an idea elsewhere of creating a string of comma separated values with the photo ID and the description. I'd store it on the MySQL database and then call upon it when I have my script assemble the gallery on the page. I'd use explode to create an array of the photo ID and its description, then call on that to fill in the gaps...thus less API calls and a faster page.
So in the back-end admin, I have a form where I set up the information for the gallery, and I hand a Set ID. The script would then go through and make this string of separated values ("|~|" as a separation). Here's what I came up with:
include("phpFlickr.php");
$f = new phpFlickr("< api >");
$descArray = "";
// This will create an Array of Photo ID from the Set ID.
// $setFeed is the set ID brought in from the form.
$photos = $f->photosets_getPhotos($setFeed);
foreach ($photos['photoset']['photo'] as $photo) {
$returnDesc = array();
$photoID = $photo['id'];
$rsp = $f->photos_getInfo($photoID);
foreach ($rsp as $pic) {
$returnDesc[] = htmlspecialchars($pic['description'], ENT_QUOTES);
}
$descArray .= $photoID."|~|".$returnDesc[0]."|~|";
}
The string $descArray would then be placed in the MySQL string that puts it into the database with other information brought in from the form.
My first question is was I correct in using a second foreach loop to get those descriptions? I tried following other examples all over the net that didn't use that, but they never worked. When I brought on the second foreach, then it worked. Should I have done something else?
I noticed the data returned would be two entries. One being the description, and the other just an "o"...hence the array $returnDesc so I could just get the one string I wanted and not the other.
Second question is if I made this too complicated or not. I like to try to learn to write cleaner/leaner code, and was looking for opinions.
Suggestions on improvement are welcome. Thank you in advance.
I'm not 100% sure as I've just browsed the source for phpFlickr, and looked the the Flickr API for the getInfo() call. But let me have a go anyway :)
First off, it looks like you shouldn't need that loop, like you mention. What does the output of print_r($rsp); look like? It could be that $rsp is an array with 1 element, in which case you could ditch the inner loop and replace it with something like $pic = $rsp[0]; $desc = $pic['description'];
Also, I'd create a new "description" column in your database table (that has the photo id as the primary key), and store the description in their on its own. Parsing db fields like that is a bit of a nightmare. Lastly, you might want to force htmlspecialchars to work in UTF8 mode, cause I don't think it does by default. From memory, the third parameter is the content encoding.
edit: doesn't phpFlickr have its own caching system? Why not use that and make the cache size massive? Seems like you might be re-inventing the wheel here... maybe all you need to do is increase the cache size, and make a getDescription function:
function getDescription ($id)
{
$rsp = $phpFlickr->photos_getInfo ($id);
$pic = $rsp[0];
return $pic['description'];
}

[DataGridClass]: How to make second column of the resultset a hyperlink?

I am using following class to show a grid like appearance with pagination on my home page. The class is very good and is working fine.
When the grid shows records, I just want to make the second column values as a hyperlink. I tried adding a href ... in the class where $c is updating, but it is not working. Can anyone help me out.
This class also uses "style.css" file that is also available from the link below. Are any changes needed there?
http://www.webmastergate.com/php/paginate-query-results.html
In the function getRows(), near the very last lines of the function where the $c variable is set. You have to somehow test whether this is the column you want to add the link. Suggest that you set up another associative array which store a key and a callback function
$r = '';
while ($row = mysql_fetch_assoc($result)) {
$c = '';
foreach($row as $key=>$field) {
//manipulate data here
$c .= $this->fmtField($key, $field);
}
$r .= sprintf($this->rowfmt, $cr ? $classodd : $classeven, $c);
$cr = 1 - $cr;
}
Another datagrid I will recommend is http://www.eyesis.ca/projects/datagrid.html - it partly removes the need to add in link as you can add custom actions to each row.
You can't. You can delegate the responsibility to the formatting to the mysql query for a possible workaround.
for example you can format the query like this one:
SELECT firstField,
concat ('', thirdField,'') as link_column,
....
assuming that in the second field you have the URL and in the third one you saved the text of the link.
Another solution (no text) can be
SELECT firstField,
concat ('', secondField,'') as link_column,
....
If you need to show the URL other than make the link.
I've perused the class and think there aren't other solution without modifying it because you can't address a single column in a row.

Categories