Just somewhere to keep my notes while I'm playing.

Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Saturday, July 25, 2009

Reading from a file

I have started playing with a new database, that will allow the costing of simple recipes. Here's the schema (so far):



DROP TABLE IF EXISTS recipe.ingredient;
DROP TABLE IF EXISTS recipe.item;
DROP TABLE IF EXISTS recipe.unit;

CREATE TABLE recipe.unit (
id INT NOT NULL,
name VARCHAR(10) NOT NULL,
PRIMARY KEY (id)
) TYPE = INNODB;

CREATE TABLE recipe.item (
code VARCHAR(10) NOT NULL,
name VARCHAR(50) NOT NULL,
unitid INT NOT NULL,
cost DECIMAL(10,2) NOT NULL,
PRIMARY KEY (code),
FOREIGN KEY (unitid) REFERENCES unit(id)
) TYPE = INNODB;

CREATE TABLE recipe.ingredient (
recipe_code VARCHAR(10) NOT NULL,
ingred_code VARCHAR(10) NOT NULL,
quantity DECIMAL(10,2) NOT NULL,
FOREIGN KEY (recipe_code) REFERENCES item (code),
FOREIGN KEY (ingred_code) REFERENCES item (code)
) TYPE = INNODB;



First thing to do is to populate the unit table.


C:\Documents and Settings\Tim\My Documents\DB\Recipe\sql>more unit.txt
1,litre
2,each
3,gram

C:\Documents and Settings\Tim\My Documents\DB\Recipe\sql>

mysql> LOAD DATA LOCAL INFILE 'unit.txt' REPLACE INTO TABLE recipe.unit FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'
-> ;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Deleted: 0 Skipped: 0 Warnings: 0

mysql> select * from unit;
+----+-------+
| id | name |
+----+-------+
| 1 | litre |
| 2 | each |
| 3 | gram |
+----+-------+
3 rows in set (0.00 sec)

mysql>


Note: the stupid 'LINES TERMINATED' option used because I'm running on a stupid OS that uses Character Return Line Feeds for it's line termination.

Then the PHP script to load some raw materials:


C:\Documents and Settings\Tim\My Documents\DB\Recipe\php>more rawingred.txt
EGG,Egg,2,15
FLOUR,Flour,3,0.01
MILK,Milk,1,75

C:\Documents and Settings\Tim\My Documents\DB\Recipe\php>more rawingredload.php
<?php
function openMyDB($dbname)
{
include("DBInfo.inc");
$con = mysql_connect($mydbhost,$mydbuser,$mydbpassword);
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
return $con;
}

$con = openMyDB("recipe");

$file=fopen("rawingred.txt","r") or exit("Unable to open file!");
while(!feof($file)) {
$ingred = fgets($file);
list($code, $name, $unitid, $cost) = split(',', $ingred);
echo "$code\t$name\t$unitid\t$cost\n";
$sql="INSERT INTO item (code, name, unitid, cost)
VALUES ('$code','$name','$unitid','$cost')";
if (!mysql_query($sql,$con)) {
die('Error: ' . mysql_error());
}
echo "1 record added\n";
}
fclose($file);

?>
C:\Documents and Settings\Tim\My Documents\DB\Recipe\php>php rawingredload.php
EGG Egg 2 15

1 record added
FLOUR Flour 3 0.01

1 record added
MILK Milk 1 75
1 record added


C:\Documents and Settings\Tim\My Documents\DB\Recipe\php>

mysql> select * from item;
+-------+-------+--------+-------+
| code | name | unitid | cost |
+-------+-------+--------+-------+
| EGG | Egg | 2 | 15.00 |
| FLOUR | Flour | 3 | 0.01 |
| MILK | Milk | 1 | 75.00 |
+-------+-------+--------+-------+
3 rows in set (0.00 sec)

mysql>

Wednesday, July 22, 2009

Compare the Perl with PHP

I had this idea that I should write exactly the same code in PHP that I had just written in Perl, just to compare.

<?php
function openMyDB()
{
include("DBInfo.inc");
$con = mysql_connect($mydbhost,$mydbuser,$mydbpassword);
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("cddb", $con);
return $con;
}

$con = openMyDB();

mysql_select_db("cddb", $con);

print "Name\t\tTitle\n";
$result = mysql_query("SELECT artist.name, cd.title FROM artist, cdtable AS cd WHERE artist.id = cd.artid");
while ($row = mysql_fetch_array($result)) {
echo $row['name'] . "\t" . $row['title'] . "\n" ;
}
mysql_free_result($result);
mysql_close($con);
?>

D:\Database\CDDB\Reports>php CDRep.php
Name Title
Phatfish Guaranteed
Phatfish 15
Bethany Dillon Waking Up
Bethany Dillon Bethany Dillon
Bethany Dillon Imagination
Nick Drake Made To Love Magic
Nick Drake Five Leaves Left
Nick Drake Bryter Layter

D:\Database\CDDB\Reports>

So, which do you prefer?

Please note that:

include("DBInfo.inc");

is my own code (for what it's worth) that we've seen in previous examples.

D:\Database\CDDB\Reports>more DBInfo.inc
<?php
$mydbhost="localhost";
$mydbuser="myuser";
$mydbpassword="mypassword";
?>

D:\Database\CDDB\Reports>

Tuesday, June 16, 2009

Improving the menus

It would be great if one single program were to be flexible enough to handle all the menus. After all, they are in a single database table.

The idea is to pass the program a parameter telling it which menu to show. It will test, and if no menu has been requested, it will show the main menu.

I'll also move tings around to put the database open and closing in to functions, and the head and tail printing as well.

One thing to bear in mind is that the menu header is currently hard code, and this will need to be pulled from the database.

So, create a table to store the menu details!

We'll need a primary index on the menus table:


CREATE TABLE menus (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20),
title VARCHAR(40),
description VARCHAR(80),
last_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP (),
PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE cddb.menuitems (
menuid INT NOT NULL,
itemno INT NOT NULL,
itemtext VARCHAR(50) NOT NULL,
itemlink VARCHAR(150) NOT NULL,
last_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP (),
FOREIGN KEY (menuid) REFERENCES menus(id) ON DELETE CASCADE
) ENGINE=INNODB;



And repopulate:



INSERT INTO cddb.menus (name, title, description) values ('mainmenu','Main Menu', 'Welcome to my CD Collection');
INSERT INTO cddb.menus (name, title, description) values ('listmenu','List Menu', 'List Details of my CD Collection');

INSERT INTO cddb.menuitems (menuid, itemno, itemtext, itemlink)
values (1,1,'Data Entry','mainmenu.php?menuname=dataentrymenu');

INSERT INTO cddb.menuitems (menuid, itemno, itemtext, itemlink)
values (1,2,'Data Lists','mainmenu.php?menuname=listmenu');

INSERT INTO cddb.menuitems (menuid, itemno, itemtext, itemlink)
values (1,3,'Reports','mainmenu.php?menuname=reportsmenu');

INSERT INTO cddb.menuitems (menuid, itemno, itemtext, itemlink)
values (2,1,'List Publisher','publishers.php');
INSERT INTO cddb.menuitems (menuid, itemno, itemtext, itemlink)
values (2,2,'List Artists','artists.php');
INSERT INTO cddb.menuitems (menuid, itemno, itemtext, itemlink)
values (2,3,'CDs by Artists','lcdsbyartist.php');
INSERT INTO cddb.menuitems (menuid, itemno, itemtext, itemlink)
values (2,4,'Tracks by CD','track.php');



Finally - rewrite the menu PHP


<?php
function openMyDB()
{
include("DBInfo.inc");
$con = mysql_connect($mydbhost,$mydbuser,$mydbpassword);
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("cddb", $con);
return $con;
}

function closeMyDB($con)
{
mysql_close($con);
}

function writeHead($MenuName)
{
$MyQuery = "SELECT title, description FROM menus m ";
$MyQuery = $MyQuery . "WHERE m.name = '" . $MenuName . "'";

$result = mysql_query($MyQuery);
$row = mysql_fetch_array($result);

echo "<html>\n<head>\n<title>" . $row['title'] . "</title>\n</head>\n";
echo "<body>\n";
echo "<h1>" . $row['description'] . "</h1>\n";
mysql_free_result($result);
}

function writeTail()
{
echo "</body>\n</html>";
}

// Main Program starts here

$mycon=openMyDB();

if ( empty($_GET['menuname']))
$MyMenuName='mainmenu';
else
$MyMenuName=$_GET['menuname'];


writehead($MyMenuName);
echo "<ol>\n";

$MyQuery = "SELECT itemtext, itemlink, itemno FROM menus m, menuitems mi ";
$MyQuery = $MyQuery . "WHERE m.name = '" . $MyMenuName . "' ";
$MyQuery = $MyQuery . "and m.id=mi.menuid order by itemno";

$result = mysql_query($MyQuery);
while ($row = mysql_fetch_array($result)) {
echo "<li>\n";
echo "<a href=\"" . $row['itemlink'] . "\">";
echo $row['itemtext'] . "</a>";
echo "\n</li>\n";
}
mysql_free_result($result);
echo "</ol>";
writetail();
closeMyDB($mycon);

?>

Tuesday, June 9, 2009

Tidying up the code

I have decided to tidy up the code a little. I have moved the database details in to a file that gets included, and moved the database opening and closing into functions. This bit was (slightly) interesting (in fact almost too interesting to be included in this otherwise boring blog). The database open function has to return a value that points to the open database, and then we have to pass that value to the database close function. There - that was exciting wasn't it!



<?php

function openMyDB()
{
include("DBInfo.inc");
$con = mysql_connect($mydbhost,$mydbuser,$mydbpassword);
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("cddb", $con);
return $con;
}

function closeMyDB($con)
{
mysql_close($con);
}

function writeHead()
{
echo "<html>\n<head>\n<title>CDs By Artists</title>\n</head>\n";
echo "<body>\n";
echo "<h1>CDs By Artists</h1>\n";
}

function writeTail()
{
echo "</body>\n</html>";
}


function writeMenu()
{
echo "<form action=\"" . $_SERVER['PHP_SELF'] . "\" method=\"post\">\n";
echo "<select name=\"artid\">\n";

$result = mysql_query("SELECT id, name FROM artist order by name");
while ($row = mysql_fetch_array($result)) {
echo "<option value=\"";
echo $row['id'] . "\">".$row['name'];
echo "</option>\n";
}
mysql_free_result($result);
echo "</select>\n";
echo "<input type=\"submit\" value=\"Submit\">";
echo "</form>\n";
}

function writeDetails($artid)
{
$result = mysql_query("SELECT name FROM artist where id = " . $artid . ";");
$row = mysql_fetch_array($result);
echo "<h3>" . $row['name'] . "</h3>\n";
mysql_free_result($result);
$result = mysql_query("SELECT title, yearpublished from cdtable where artid = " . $artid . ";");
echo "<table>\n<tr><th>Year Published</th><th>Title</th></tr>\n";
while ($row = mysql_fetch_array($result)) {
echo "<tr><td>" . $row['yearpublished'] . "</td>";
echo "<td>" . $row[title] . "</td></tr>\n";
}
mysql_free_result($result);
echo "</table>\n";
}


#
## Main Body
#

$mycon=openMyDB();
writehead();
if ( empty($_POST['artid']) )
{
writeMenu();
}
else
{
writeDetails($_POST['artid']);
}

writetail();
closeMyDB($mycon);
?>


And the incude file looks like this:

<?php
$mydbhost="localhost";
$mydbuser="timj";
$mydbpassword="xxxxxx";
?>


That's enough excitement for one day!

Friday, June 5, 2009

My first form in PHP

This form checks to see if it has been past a parameter. If not it displays a pull-down list of the artists on file. If it has been passed a value, it uses that value to pull out the CDs on file for an artist. That way the same piece of code is used twice.

I've tried to put things in functions to make it a little more tidy.


<?php
function writeHead()
{
echo "<html>\n<head>\n<title>CDs By Artists</title>\n</head>\n";
echo "<body>\n";
echo "<h1>CDs By Artists</h1>\n";
}

function writeTail()
{
echo "</body>\n</html>";
}


function writeMenu()
{
echo "<form action=\"" . $_SERVER['PHP_SELF'] . "\" method=\"post\">\n";
echo "<select name=\"artid\">\n";

$result = mysql_query("SELECT id, name FROM artist order by name");
while ($row = mysql_fetch_array($result)) {
echo "<option value=\"";
echo $row['id'] . "\">".$row['name'];
echo "</option>\n";
}
mysql_free_result($result);
echo "</select>\n";
echo "<input type=\"submit\" value=\"Submit\">";
echo "</form>\n";
}

function writeDetails($artid)
{
$result = mysql_query("SELECT name FROM artist where id = " . $artid . ";");
$row = mysql_fetch_array($result);
echo "<h3>" . $row['name'] . "</h3>\n";
mysql_free_result($result);
$result = mysql_query("SELECT title, yearpublished from cdtable where artid = " . $artid . ";");
echo "<table>\n<tr><th>Year Published</th><th>Title</th></tr>\n";
while ($row = mysql_fetch_array($result)) {
echo "<tr><td>" . $row['yearpublished'] . "</td>";
echo "<td>" . $row[title] . "</td></tr>\n";
}
mysql_free_result($result);
echo "</table>\n";
}


#
## Main Body
#
$con = mysql_connect("localhost","timj","xxxxxx");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("cddb", $con);

writehead();
if ($_POST['artid']=="") writeMenu();
else writeDetails($_POST['artid']);

writetail();

mysql_close($con);
?>

And here is the Artists table:


<?php
echo "<html><head><title>Artists</title></head>";
echo "<body>";
echo "<h1>Artists in my CD Collection</h1>";
echo "<ol>\n";
$con = mysql_connect("localhost","timj","xxxxx");
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db("cddb", $con);

$result = mysql_query("SELECT name FROM artist order by name");
while ($row = mysql_fetch_array($result)) {
echo "<li>\n";
echo $row['name'] ;
echo "</li>\n";
}
mysql_free_result($result);
mysql_close($con);
echo "</ol>";
echo "</body>";
echo "</html>";
?>


Pretty much the same as the Publishers screen.

Thursday, June 4, 2009

Listing Data

Here is the code for my Publishers list:


<?php
echo "<html><head><title>List Menu</title></head>";
echo "<body>";
echo "<h1>Explore My CD Collection</h1>";
echo "<ol>\n";
$con = mysql_connect("localhost","timj","xxxxxxx");
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db("cddb", $con);

$result = mysql_query("SELECT itemtext, itemlink, itemno FROM menus WHERE name = 'listmenu' order by itemno");
while ($row = mysql_fetch_array($result)) {
echo "<li>\n";
echo "<a href=\"" . $row['itemlink'] . "\">";
echo $row['itemtext'] . "</a>";
echo "\n</li>\n";
}
mysql_free_result($result);
mysql_close($con);
echo "</ol>";
echo "</body>";
echo "</html>";
?>


The Output html looks like this:

D:\Database\CDDB\DocRoot>php publishers.php
<html><head><title>Publsihers</title></head><body><h1>Publishers in my CD Collection</h1><ol>
<li>
EMI</li>
<li>
SONY</li>
</ol></body></html>
D:\Database\CDDB\DocRoot>

Friday, May 8, 2009

PHP - My website's menus

I have decided that I want all the menus on my web site to be dynamic, driven from the database rather than hard-coded in HTML. This has the advantage that it you want to add a menu item, you just add it to the database, you don't need to recode your menus. Of course it requires a little more work up front, but that's what we are here for!

Step 1:
Create a database table to hold your menus:


CREATE TABLE cddb.menus (
name VARCHAR(20) NOT NULL,
itemno INT NOT NULL,
itemtext VARCHAR(50) NOT NULL,
itemlink VARCHAR(150) NOT NULL
);


Step 2:
Create a text file with your menus defined in it:

mainmenu,1,Data Centre,dataentry.php
mainmenu,2,Data Lists,datalists.php
mainmenu,3,Reports,reports.php
listmenu,1,List Publishers,publishers.php
listmenu,2,List Artists,artists.php
listmenu,3,CDs by Artist,lcdsbyartist.php
listmenu,4,Tracks by CD,track.php


I am working on a Windows laptop, and I found that the load command didn't handle the windows EOL characters well, it corrupts the final field. I'm sure that there is a way around this, but I ended up using a dos2unix command in cygwin.

Step 3:
Import your menu data into your database:

mysql> LOAD DATA LOCAL INFILE 'menus.txt' INTO TABLE cddb.menus FIELDS TERMINATED BY ',';
Query OK, 7 rows affected, 7 warnings (0.00 sec)
Records: 7 Deleted: 0 Skipped: 0 Warnings: 7

mysql> select * from menus;
+----------+--------+-----------------+------------------+
| name | itemno | itemtext | itemlink |
+----------+--------+-----------------+------------------+
| mainmenu | 1 | Data Centre | dataentry.php |
| mainmenu | 2 | Data Lists | datalists.php |
| mainmenu | 3 | Reports | reports.php |
| listmenu | 1 | List Publishers | publishers.php |
| listmenu | 2 | List Artists | artists.php |
| listmenu | 3 | CDs by Artist | lcdsbyartist.php |
| listmenu | 4 | Tracks by CD | track.php |
+----------+--------+-----------------+------------------+
7 rows in set (0.00 sec)

mysql>


Step 4:

Final Step, to get write the PHP to create the index page.


<?php
echo "<html><head><title>Main Menu</title></head>";
echo "<body>";
echo "<h1>Welcome to my CD Collection</h1>";
echo "<ol>\n";
$con = mysql_connect("localhost","timj","xxx");
if (!$con) {
die('Could not connect: ' . mysql_error());
}

mysql_select_db("cddb", $con);

$result = mysql_query("SELECT itemtext, itemlink, itemno FROM menus WHERE name = 'mainmenu' order by itemno");
while ($row = mysql_fetch_array($result)) {
echo "<li>\n";
echo "<a href=\"" . $row['itemlink'] . "\">";
echo $row['itemtext'] . "</a>";
echo "\n</li>\n";
}
mysql_free_result($result);
mysql_close($con);
echo "</ol>";
echo "</body>";
echo "</html>";
?>


And that's all there is to it!