I'm building a food menu on a webpage. This menu includes drink items like Wine and Beer. Currently, they are categorized by Red or White and the type of wine (Pinot Grigio, Chardonnay, etc.). I have entered these wine items into a MySQL database with the following columns/values:
id(int), name(varchar), type(varchar), price_bottle(decimal), price_glass(decimal), red(bool)
My Current code:
$result = mysql_query("SELECT * FROM Wines WHERE type = 'Pinot Grigio' ");
while($row = mysql_fetch_array($result)) {
$name = $row['name'];
$type = $row['type'];
$price_bottle = $row['price_bottle'];
$price_glass = $row['price_glass'];
echo
"<div class='foodmenu-item'>
<div class='foodmenu-text'>
<h2>" . $type . "</h2>
<p>" . $name . "</p>
</div>
<div class='foodmenu-price'>
<p>$" . $price_bottle . " / " . $price_glass . "</p>
</div>
</div>";
}
Which is fine if I wanted to display each item out individually, but I want to Group by 'type' of wine (Pinot Grigio, Chardonnay, etc.) and then list each name of the wine under that 'type' so my CSS looks neat and organized.
For Example:
PINOT GRIGIO
Nobllissimo
Riff
CHARDONNAY
The Crusher
Bogle
Using the "GROUP BY" SQL syntax only displays the first result with my current code. All my attempts at making a foreach statement result in error, I'm not sure where to turn next.
How can I achieve this?
good manner is don't simply use "*", but list of columns
(reason: select only data which realy want to use - better performance, second if you later want add or change columns in the table then your life will be simplier ;-) )
I think you can try, select all from small table and only sort the data - type and name, then in while cycle do it group about type for your menu. Then you need only one query send to database and have all of it. Assumption is Wines is only small table, because select all consume a memory.
SELECT type, name, price_bottle, price_glass
FROM Wines
ORDER BY type, name;
Have you tries using 2 queries nested? Like this:
$result = mysql_query("SELECT DISTINCT(type) FROM Wines ORDER BY type");
while($row = mysql_fetch_array($result)) {
$type = $row['type'];
echo "<div class='foodmenu-item'>
<h2>" . $type . "</h2>";
$result2 = mysql_query("SELECT * FROM Wines WHERE type = '".type."' ");
while($row2 = mysql_fetch_array($result2)) {
$name = $row2['name'];
$price_bottle = $row2['price_bottle'];
$price_glass = $row2['price_glass'];
echo "
<div class='foodmenu-text'>
<p>" . $name . "</p>
</div>
<div class='foodmenu-price'>
<p>$" . $price_bottle . " / " . $price_glass . "</p>
</div>";
}
echo "</div>";
}
I'm trying to make a website to access a SQLite database and retrieve info on different people. However, I'm having some problems. Here's my code for my index page.
<?php
$db = new SQLite3('people.db');
$results = $db->query('select FirstName,LastName from People');
?>
<html>
<head>
</head>
<body>
<?php
while ($row = $results->fetchArray()) {
echo '<div class="person"><p class="name"><a href="lookup.php?first=" .
urlencode($row['FirstName']) . '&last=' . urlencode($row['LastName']) . '">' .
$row['FirstName'] . ' ' . $row['LastName'] . '</a></p></div>;
?>
}
?>
</body>
</html>
And the lookup.php code:
<?php
$db = new SQLite3('people.db');
$first = urldecode($_GET['first']);
$last = urldecode($_GET['last']);
$results = $db->query('select * from People where FirstName="' . $first . '" and LastName="' . $last . '"');
$row = $results->fetchArray();
?>
<html>
<head>
</head>
<body>
<div class="person">
Name: <?php echo $row['FirstName'] ?><br/>
Last Name: <?php echo $row['LastName'] ?><br/>
Age: <?php echo $row['Age'] ?><br/>
</div>
</body>
</html>
When I click on a person's name on the index page whose FirstName is "Denzil" and LastName is "Ezras", it works fine. lookup.php displays his FirstName, LastName, and Age. However, I run into problems when a person's first or last name has a space in it. For instance, a person whose FirstName is "James" and LastName is "De Jongh", lookup.php will show no FirstName, LastName, or Age. The URL for this page comes up as:
http://localhost/lookup.php?first=James&last=De+Jongh
I have tried using var_export in PHP to take a look at $first and $last, and they seem in order. When I copy and paste them into sqlite3.exe, it comes up with the proper values. What am I doing wrong?
try this
as i can see from the url, instead of displaying the space as %20 it display it as +
this will convert any spaces to %20 which is acceptable by the url.
$last = str_replace(' ', '%20', $last);
or you can simply use
rawurlencode($lastName);
There are three tables in MySQL: Employees, Branches, Departments. I need information to appear in the following way:
ATLANTA Branch Delivery Department Phillip J. Fry Phone: 123456
Engineering Department Turanga Leela Phone: 123457
Bender Rodriguez Phone: 123458
The simple PHP code currently:
1) Takes rows from three tables (simple SELECT query with JOIN)
2) Puts them in row (mysql_fetch_assoc)
3) Displays using the PHP While loop
The result is then like this:
ATLANTA Branch Delivery Department Phillip J. Fry Phone: 123456
ATLANTA Branch Engineering Department Turanga Leela Phone: 123457
ATLANTA Branch Engineering Department Bender Rodriguez Phone: 123458
What technique (JS, jQuery, Ajax) or method can you recommend so I can pull row information using only one query and not duplicate the Branch name and Department name?
UPDATE: If I put the branch name outside the loop (using While loop), there would be multiple loops: 1) To get a branch, 2) To get a department, 3) To get all employees in that department. Loop.
UPDATE: Sharing the code:
<?php
// Create connection
$connection = mysql_connect('localhost','root', '') or die('Connection error.');
mysql_query("SET NAMES 'utf8'", $connection);
mysql_select_db("eReference");
// Check Employees
$query = "SELECT Employees.fName, Employees.lName, Department.deptName, Branch.branchName, ".
"FROM Employees ".
"LEFT JOIN Department ".
"ON Employees.department = Department.id ".
"LEFT JOIN Branch ".
"ON Employees.branch = Branch.id ;";
$result = mysql_query($query, $connection) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
?>
<h2><?php echo $row['branchName']; ?></h2>
<?php if ($row['deptName']) echo "<h3>" . $row['deptName'] . "</h3>"; ?>
<h4><?php echo $row['fName'] . " " . $row['lName']; ?></h4></p>
<?php
}
?>
<?php
$i = 1; // to be incremented after printing branchName once
while ($row = mysql_fetch_assoc($result)) {
if($i == 1) { ?>
<h2><?php echo $row['branchName']; $i ++; ?></h2>
<?php } ?>
<?php if ($row['deptName']) echo "<h3>" . $row['deptName'] . "</h3>"; ?>
<h4><?php echo $row['fName'] . " " . $row['lName']; ?></h4></p>
<?php } ?>
Just add a variable $i = 1 and check before printing if it is equal to 1. After printing it for first time, increment it.
It is just addition of an if statement.
Hope this helps.
This is how I would do it.
Create a multi-dimensional array with the data, and iterate through the array to render the output.
This will not be the most efficient in terms of memory usage, but unless you have thousands of rows of data, it probably won't be an issue.
The benefit of this, is that the html rendering code is much simpler and easier to understand, plus sql and html are not intermingled. (which is good for code maintenance)
<?php
// Create connection
$connection = mysql_connect('localhost','root', '') or die('Connection error.');
mysql_query("SET NAMES 'utf8'", $connection);
mysql_select_db("eReference");
// Check Employees
$query = "SELECT Employees.fName, Employees.lName, Department.deptName, Branch.branchName, ".
"FROM Employees ".
"LEFT JOIN Department ".
"ON Employees.department = Department.id ".
"LEFT JOIN Branch ".
"ON Employees.branch = Branch.id ;";
// note you probably want to add an order by statement here too, to ensure consistent sorting
$result = mysql_query($query, $connection) or die(mysql_error());
$data = array();
// build a multi-dimensional array from the result set
while ($row = mysql_fetch_assoc($result)) {
$data[($row['branchName'])][($row['deptName'])][] = array(
'name' => "{$row['fName']} {$row['lName']}",
'phone' => $row['phone'] // add phone, doesn't exist in original query, but just to illustrate how it would work
);
}
// sql finishes here
?>
<?php
// html rendering
// use htmlentities to escape any html chars, such as < > etc
foreach ($data as $branchName => $departments) {
echo '<h2>',htmlentities($branchName),'</h2>';
foreach ($departments as $deptName => $employees) {
foreach ($employees as $employee) {
echo '<h3>',htmlentities($deptName),'</h3>';
echo '<h4>',htmlentities($employee['name']),'</h4>';
echo '<h4>',htmlentities($employee['phone']),'</h4>';
}
}
}
?>
The result gotten from your sql should be an array so use a while loop to iterate throw the array while echo the result of the current index
Maybe this will work..
<?php
$deptName;
while($row = mysql_fetch_assoc($result))
{
if ($row['deptName'])
{
if ($deptName != $row['deptName'])
{
echo "<h3>" . $row['deptName'] . "</h3>";
$deptName = $row['deptName'];
}
}
}
?>
$result = mysql_query($query, $connection) or die(mysql_error());
$newarray = array();
$i = 0;
while ($row = mysql_fetch_assoc($result)) {
$newarray[$i]['deptName'] = $row['deptName'];
$newarray[$i]['fName'] = $row['fName'];
$newarray[$i]['lName'] = $row['lName'];
$i++;
}
<h2><?php echo $newarray[0]['branchName']; ?></h2>
while($newarray){
?>
<?php if ($newarray['deptName']) echo "<h3>" . $newarray['deptName'] . "</h3>"; ?>
<h4><?php echo $newarray['fName'] . " " . $newarray['lName']; ?></h4></p>
}
?>
So, this is what it did:
$query = "SELECT Employees.lName, Employees.fName, Employees.mName, Position.position, ".
"department.deptName, department.deptId, ".
"Branch.branchName, Branch.branchId, ContactInformation.* ".
"FROM Employees ".
"LEFT JOIN Position ".
"ON Employees.position = Position.id ".
"LEFT JOIN Department ".
"ON Employees.department = Department.deptId ".
"LEFT JOIN Branch ".
"ON Employees.branch = Branch.branchId ".
"LEFT JOIN ContactInformation ".
"ON Employees.contactInformation = ContactInformation.id ".
"ORDER BY Employees.branch, Employees.department ASC;";
$result = mysql_query($query, $connection) or die(mysql_error());
$arrayOfEmployees = array();
while ($row = mysql_fetch_assoc($result)) {
$arrayOfEmployees[($row['branchName'])][($row['deptName'])][] = array(
'lName' => $row['lName'],
'fName' => $row['fName'],
'mName' => $row['mName'],
'position' => $row['position'],
'lPhone1' => $row['lPhone1'],
'lPhone2' => $row['lPhone2'],
'mPhone' => $row['mPhone'],
'fax' => $row['fax'],
'office' => $row['office'],
'email' => $row['email']
);
}
foreach($arrayOfEmployees as $branchName => $arrayOfDepartments) {
echo "<h2>".$branchName."</h2>";
foreach($arrayOfDepartments as $deptName => $arrayOfEmployeeContacts) {
echo '<h3>',htmlentities($deptName),'</h3>';
foreach($arrayOfEmployeeContacts as $employeeContacts) {
echo "<h4>".$employeeContacts["lName"]." ".$employeeContacts["fName"]." ".$employeeContacts["mName"]."</h4>";
echo "<p>";
if($employeeContacts["position"]) echo $employeeContacts["position"]."<br>";
$num = $employeeContacts["lPhone1"];
if($employeeContacts["lPhone1"]) echo "+".substr($num,0,1)." (".substr($num,1,4).") "." ".substr($num,5,2)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
$num = $employeeContacts["lPhone2"];
if($employeeContacts["lPhone2"]) echo "+".substr($num,0,1)." (".substr($num,1,4).") "." ".substr($num,5,2)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
$num = $employeeContacts["mPhone"];
if($employeeContacts["mPhone"]) echo "+".substr($num,0,1)." (".substr($num,1,3).") "." ".substr($num,4,3)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
$num = $employeeContacts["fax"];
if($employeeContacts["fax"]) echo "+".substr($num,0,1)." (".substr($num,1,4).") "." ".substr($num,5,2)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
if($employeeContacts["email"]) echo "".$employeeContacts["email"]."<br>";
if($employeeContacts["office"]) echo "Кабинет — ".$employeeContacts["office"];
echo "</p>";
}
}
}
Tested. The solution works well dynamically — just add more branches and departments into the database. Here is the efficiency check against the method I originally used (in microseconds):
Array-based Original
1 1.015 1.012
2 1.016 1.02
3 1.026 1.013
4 1.015 1.002
5 1.026 1.02
6 1.014 1.02
7 1.013 1.019
8 1.005 1.014
9 1.013 1.006
10 1.021 1.015
Average 1.0164 1.0141
Didn't know how to word the title sorry. Basically I have a comments system, it works really simply, selects the uid of the post from a DB, then just outputs the comments tied to that UID from another DB.
The nature of the comments system is that every poster is anonymous, because of that, it's hard to track whether you're communicating with the same person or not, for that reason, I want to make the div wrapped around the comment be a specific colour, and for each comment by that person on that post to be that colour. The only thing that ties a users comments together is the IP address.
My code thus far:
$sql = "SELECT * FROM anonpost_com WHERE uid = '$uid' ORDER BY date DESC";
$result = mysql_query($sql) or print ("Can't select entry from table anonpost.<br />" . $sql . "<br />" . mysql_error());
while($row = mysql_fetch_array($result)) {
$date = date("l F d Y", strtotime($row['date']));
$comment = stripslashes($row['comment']);
$uid = ($row['uid']);
$cid = ($row['cid']);
$ip = ($row['ip']);
?>
<div id="comments" style="border:1px solid <?php echo $colour; ?>;">
<p><?php echo $comment; ?></p>
<h4>by <i>Anonymous</i> on <?php echo $date; ?></h4>
</div>
<?php
}
?>
$colour comes from:
$colour = dechex(rand(0,10000000);
But I'm unsure how to make $colour the same for every instance of the same IP on a comment...
Any help would be appreciated!
I would agree that IP address might not be the best solution, but to do that:
$sql = "SELECT * FROM anonpost_com WHERE uid = '$uid' ORDER BY date DESC";
$colours = array();
$result = mysql_query($sql) or print ("Can't select entry from table anonpost.<br />" . $sql . "<br />" . mysql_error());
while($row = mysql_fetch_array($result)) {
$date = date("l F d Y", strtotime($row['date']));
$comment = stripslashes($row['comment']);
$uid = ($row['uid']);
$cid = ($row['cid']);
$ip = ($row['ip']);
if (!isset($colours[$ip])) {
$colours[$ip] = dechex(rand(0,10000000);
}
$colour = $colours[$ip];
?>
<div id="comments" style="border:1px solid <?php echo $colour; ?>;">
<p><?php echo $comment; ?></p>
<h4>by <i>Anonymous</i> on <?php echo $date; ?></h4>
</div>
<?php
}
?>
Note that the colour will change each time the page loads.
I'm pretty new to php, and for that matter server scripting in general (so go easy on me)
But regardless of that I managed to create this, the first half of a comment system:
<html>
<body>
<form name="Comment" action="InsertComment.php" method="POST">
Name: <input type="text" name="name" /><br>
Comment: <br><textarea style="height: 100px; width: 600px;" name="comment"></textarea><br>
<input id="Special_ID" name="id" value="<?php $unixtime = time(); echo $unixtime; ?>">
<!--^Gathers a unique id^-->
<input type="submit" />
</form>
</body>
</html>
Once submitted -->
<?php
$con = mysql_connect("Blaa", "Blaa", "Blaa");
if(!$con) {
die('Could not connect ' . mysql_error());
}
sql_select_db("Comments", $con);
$sql = "INSERT INTO Posts (Name, Comment, ID)
VALUES('$_POST[name]', '$_POST[comment]', '$_POST[id]')";
?>
This is exactly what I wanted, a user puts in their name, a comment, and a unique post id (time stamp) is generated, then it is all sent to mysql.
But now I'm dumb found as to how I can post this to another page..
I assumed something like:
if(ID == [the id of that post]) {
//$_GET the mysql stuff
//Post inside a specially made div or something
}
Along the lines of that, but I have no clue how to put that into practise :/
Any ideas?
Oh and Please don't suggest an echo type post, I've done that and it's not at all what I want.
**Also this is just the basic code, I don't need suggestions on how to touch it up just yet, also errors in this is only due to my sleep deprivation, the code does work.
As #Marc B has said, you'll first want to fix your SQL injection holes using mysql_real_escape_string. Change your insert statement to
$sql = "INSERT INTO Posts (Name, Comment, ID)
VALUES('" . mysql_real_escape_string($_POST['name']) . "', '" . mysql_real_escape_string($_POST['comment']) . "', '" . mysql_real_escape_string($_POST['id']) . "')";
To display your comment, try this
$sql = "SELECT Name, Comment, ID
FROM Posts
WHERE ID = '" . mysql_real_escape_string($_GET['PostID']) . "'";
$query = mysql_query($sql);
echo "<div id=\"comments_container\">";
while ($row = mysql_fetch_assoc($query))
{
echo "<div class=\"comment\">";
echo "<div class=\"name\">" . $row['Name'] . "</div>";
echo "<div class=\"comment_body\">" . $row['Comment'] . "</div>";
echo "</div>"
}
echo "</div>";
Then CSS style your DIVs using IDs and classes.
Just an example using mysql_fetch_object
Please sanitize your $_GET data before inserting to MySQL, this is a huge injection security flaw.
$sql = "SELECT * FROM Posts WHERE id={$id}"
$result = mysql_query($sql);
$obj = mysql_fetch_object($result)
if(is_object($obj))
{
echo "Welcome " . $obj->Name;
}
A full length example is given here:
http://manzur-ashraf.com/code/auto_commenting_system/Automatic_Commenting_System_and_Email_notification_using_PHP_and_MYSQL.htm
In addition to using a MYSQL database to store the comments, you can also post email to the admin about new comments.