// every page needs to start with these basic things
// I'm using a separate config file. so pull in those values
require("config.inc.php");
// pull in the file with the database class
require("Database.class.php");
// create the $db object
$db = new Database(DB_SERVER, DB_USER, DB_PASS, DB_DATABASE);
// connect to the server
$db->connect();
#####
// your main code would go here
#####
// and when finished, remember to close connection
$db->close();
// update an existing record using query_update()
$data['comments'] = 3536;
$data['title'] = "New Article";
// special cases supported for update: NULL and NOW()
$data['author'] = "NULL";// it knows to convert NULL and NOW() from a string
// also supports increment to the current database value
// will also work with a negative number. eg; INCREMENT(-5)
$data['views'] = "INCREMENT(1)";
// query_update() parameters
// table name (ideally by calling a constant defined in config file)
// assoc array with data (does not need escaped)
// where condition
$db->query_update(TABLE_NEWS, $data, "news_id='46'");
// would create the query:
// UPDATE `news` SET `comments`='3536', `title`='New Article',
// `author`=NULL, `views`=`views` + 1 WHERE news_id='46'
// insert a new record using query_insert()
$data['news_id'] = 47;
$data['title'] = "You're Top"; // insert() will auto escape it for us
$data['created'] = "NOW()";// it knows to convert NULL and NOW() from a string
// query_insert() parameters
// table name (ideally defined as a constant, but did not for this example)
// assoc array with data (does not need escaped)
// query_insert() returns
// primary id of the inserted record. you can collect or ignore
$primary_id = $db->query_insert("news", $data);
// then use the returned ID if you want
echo "New record inserted: $primary_id";
// would create the query:
// INSERT INTO `news` (`news_id`,`title`,`created`)
// VALUES ('47', 'Your\'re Top', NOW())
// escape() query() and fetch_array()
// pullout the first 10 entries where referrer came from google
// using defined TABLE_USERS table name from config
// $db->escape() escapes string to make it safe for mysql
$url = "http://www.google.com/";
$sql = "SELECT user_id, nickname FROM `".TABLE_USERS."`
WHERE referrer LIKE '".$db->escape($url)."%'
ORDER BY nickname DESC
LIMIT 0,10";
$rows = $db->query($sql);
while ($record = $db->fetch_array($rows)) {
echo "<tr><td>$record[user_id]</td>
<td>$record[nickname]</td></tr>";
}
// using escape() and fetch_all_array()
// pullout the first 10 entries where url came from google
// using defined TABLE_USERS table name from config
// $db->escape() escapes string to make it safe for mysql
$url = "http://www.google.com/";
$sql = "SELECT user_id, nickname FROM `".TABLE_USERS."`
WHERE referer LIKE '".$db->escape($url)."%'
ORDER BY nickname DESC
LIMIT 0,10";
// feed it the sql directly. store all returned rows in an array
$rows = $db->fetch_all_array($sql);
// print out array later on when we need the info on the page
foreach($rows as $record){
echo "<tr><td>$record[user_id]</td>
<td>$record[nickname]</td></tr>";
}
// using query_first()
// get user's nickname using their unique ID
// using defined TABLE_USERS table name from config
$sql = "SELECT nickname FROM `".TABLE_USERS."`
WHERE user_id=$user_id";
// since user_id is unique, only one record needs returned
// I use $db->query_first() instead of $db->query() and fetch_array()
// $db->query_first() will return array with first record found
$record = $db->query_first($sql);
// since it only returns one record, query_first() does the fetching
// I can print off the record directly
echo $record['nickname'];
// delete a specific entry
$sql = "DELETE FROM `".TABLE_USERS."` WHERE user_id=$user_id";
$db->query($sql);
// using $db->affected_rows
// returns the number of rows in a table affected by your query
// can be used after UPDATE query (to see how many rows are updated)
// can be used after SELECT query (to see how many rows will be returned)
$sql = "SELECT nickname FROM `".TABLE_USERS."` WHERE user_id='1'";
$row = $db->query($sql);
if($db->affected_rows > 0){
echo "Success! Number of users found: ". $db->affected_rows;
}
else{
echo "Error: No user found.";
}
require("Database.class.php");
// creating and connecting to two database
$db_1 = new Database("localhost", "user", "pass", "deadwood_public");
$db_2 = new Database("localhost", "user", "pass", "deadwood_internal");
// NOTE: this is the main difference
// when I connect using connect(true) it will force open a new connection
// otherwise connect() uses the existing connection if it contains the the same info
$db_1->connect(true);
$db_2->connect(true);
// insert data into both database
$data['member_name']="John Smith";
$db_1->query_insert("members", $data);
$db_2->query_insert("members", $data);
// close the second connection
$db_2->close();
// we can still run a query to the first connection
$rows = $db_1->query("SELECT * FROM members LIMIT 0,5");
while($row = $db_1->fetch_array($rows)){
echo "<pre>".print_r($row,true)."</pre>";
}
// close the first connection
$db_1->close();
| Data Type | Column Type | Range or Description | Storage |
|---|---|---|---|
| Numeric | TinyInt | Signed values from -128 to 127 Unsigned values from 0 to 255 |
1 byte |
| Numeric | SmallInt | Signed values from -32768 to 32767 Unsigned values from 0 to 65535 |
2 bytes |
| Numeric | MediumInt | Signed values from -8388608 to 8388607 Unsigned values from 0 to 16777215 |
3 bytes |
| Numeric | Int | Signed values from -2147683648 to 2147483647 Unsigned values from 0 to 4294967295 |
4 bytes |
| Numeric | BigInt | Signed values from -9223372036854775808 to 9223372036854775807 Unsigned values from 0 to 18446744073709551615 |
8 bytes |
| Numeric | Float | Minimum non-zero values: 1.175494351E-38 Maximum non-zero values: 3.402823466E+38 |
4 bytes |
| Numeric | Double Float | Minimum non-zero values: 2.2250738585072014E-308 Maximum non-zero values: 1.7976931348623157E+308 |
8 bytes |
| Numeric | Decimal | Varies | Maximum width + 2 bytes |
| String | Char | Range 1-255 characters | Always filled max width |
| String | VarChar | Range 1-255 characters | Length of string + 1 byte |
| String | TinyBlob, TinyText | Max length 255 characters | Length of string + 1 byte |
| String | Blob, Text | Max length 65535 characters (~64KB of text) | Length of string + 2 bytes |
| String | MediumBlob, MediumText | Max length 16777216 characters (16MB of text) | Length of string + 3 bytes |
| String | LongBlob, LongText | Max length 4294967295 characters (4GB of text) | Length of string + 4 bytes |
| String | Enum ('value','value2',...) | String object that can have only one set of allowed values | 1 or 2 bytes |
| String | Set ('value','value2',...) | String object that can have one or many values of a set of allowed values. | 1, 2, 3, 4, or 8 bytes |
| Date/Time | Date | 'YY-MM-DD', 'YYYY-MM-DD', 'YYMMDD' Range "1000-01-01" to "9999-12-31" |
3 bytes |
| Date/Time | Time | 'HH:MM:SS', 'HHMMSS', 'HHMM', 'HH' Range "-838:59:59" to "838:59:59" |
3 bytes |
| Date/Time | DateTime | 'YYYY-MM-DD HH:MM:SS' "0000-01-01 00:00:00" to "9999-12-31 23:59:59" |
8 bytes |
| Date/Time | TimeStamp | 19700101000000 to sometime in the year 2037 | 4 bytes |
| Date/Time | Year | 'YYYY', 'YY' Range "1901" to "2155" | 1 byte |
Comments
Question: Joining Tables
I am attempting to get data from a joined table:
$sql = "SELECT * FROM blog, images WHERE images.parent_page = blog.id";$rows = $db->query($sql);
How would I echo out the results?
<?phpwhile ($record = $db->fetch_array($rows)) {
echo $record['blog']['entry']; //nope
echo $record['blog.entry']; //nope
}
?>
Is this possible?
Answer
I've never joined tables like that so I'm trying hard not to inject my personal syntax preferences (yours is valid, just awkward if you end up doing complex queries). But either way MySQL does not return the table names in the results set (has nothing to do with PHP). So you are just
<?phpwhile ($record = $db->fetch_array($rows)) {
echo $record['entry'];//whatever field name from blog table
echo $record['path'];//or whatever the field name from images table
}
?>
Error messages
Thanks for the excellent script. It has saved a lot of unnecessary coding. My question is how to suppress a MYSQL error message. I know that in general you would place a @ symbol before a call. My reason is that I have a setup script that is only used once. I thought that if I checked to see if the table already exists and then I would show the form (if not existed) or re-direct the user. Because there is no table, as the script hasn't been setup, then there is an error message.
There is an alternative that I have found but I am not sure that I could use it with this script.
SELECT count(*)FROM information_schema.tables
WHERE table_schema = <schema-or-db-name>
AND table_name = <table-or-view-name>
Any help would be appreciated
Answer
You could try something with "SHOW TABLES"
<?php$db->query("SHOW TABLES LIKE 'members'");
if($db->affected_rows > 0){
echo "table exists";
}
?>
If you're running initial database setup, you can also use MySQL like
CREATE TABLE IF NOT EXISTS `members` ... etcUpdating integer fields by incrementing
Hi! I use your script and like it very much! Really nice script!
As you probably agree, it's much easier to update a table using your "query_update" rather than writing the hole update query (or else you wouldn't even write it!).
I'm now facing a little problem with an update, as I'm trying to do something like:
UPDATE table_name SET field_1=345, field_2='example string', field_3=field_3+1 WHERE field_id=4If I write it like:
<?php$data['field_1'] = 345;
$data['field_2'] = "example string";
$data['field_3'] = "field_3+1";
$db->query_update(TABLE_NAME, $data, "field_id='4'");
?>
I get this resulting query:
UPDATE `table_name` SET `field_1`='345', `field_2`='example string', `field_3`='field_3+1' WHERE field_id=4And this query puts field_3 value to the integer 0, as field_3 is an integer.
How can I do this? Is it possible with the "query_update" or I'll have to use the "query"?
TIA for a reply
Answer
I would say your best bet would be to add another elseif statement like the way the "null" and "now()" are handled in query_update(). something like:
elseif(preg_match("/^increment\((\-?\d+)\)$/i",$val,$m)) $q.= "`$key` = `$key` + $m[1], ";and then you can call it like
$data['field_3']="increment(5)";// it's also case insensitive and will work with a negative number
$data['field_3']="INCREMENT(-1)";
You got me thinking and I actually really like this idea and you might see it in the official version in a future update.
Great script
Great script! I have used this for two of my major web applications, one a CRM and another a Helpdesk. As far as the mysql connections, queries, and such go, I have had no problem. Other developers were able to view the code and easily make changes as well based on your intuitive method for inserting, updating, etc. data.
I have a quick question/feature request. Have you ever created a User class that would extend this MySQL wrapper class? Currently I am using www.phpuserclass.com and simply passing the mysql link connection to it, but it is a loose integration.
beta version of user management
[edit:] v3 of the MySQL wrapper (PHP5 Singleton Class) is available now.
[edit2:] I went ahead and released a BETA version of my PHP User Login and Management for those interested in playing with it.
Insert ... on duplicate key update
In my application I do a lot of updates/inserts and to reduce the number or queries I've modified your $db->query_insert (Ver: 2.1) to include the 'ON DUPLICATE KEY UPDATE'.
<?php
#-#############################################
# desc: does an insert query with an array.
# if parameter $update is true, will update record if it already exists
# param: table (no prefix), assoc array with data, bool (UPDATE ON DUPLICATE)
# returns: id of inserted/updated record, false if error
# NOTE: "ON DUPLICATE KEY UPDATE" requires MySQL version 4.1 or higher
function query_insert($table, $data, $update=false) {
$q="INSERT INTO `".$this->pre.$table."` ";
$v=''; $n=''; $d='';
foreach($data as $key=>$val) {
$n.="`$key`, ";
if(strtolower($val)=='null') $v.="NULL, ";
elseif(strtolower($val)=='now()') $v.="NOW(), ";
else $v.= "'".$this->escape($val)."', ";
if($update) $d.="`$key`=VALUES(`$key`), ";
}
$q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .")";
if($update) $q .= " ON DUPLICATE KEY UPDATE ".rtrim($d, ', ');
$q .= ";";
if($this->query($q)){
return mysql_insert_id($this->link_id);
}
else return false;
}#-#query_insert()
?>
Weird thing...
When ON DUPLICATE KEY UPDATE is used the mysql_insert_id() function return nothing. Any ideas why?
Answer
I just tested it and the above function returns the primary ID both updating and inserting a new record on MySQL 5.0. Are you sure you have a primary/unique key set for the table you are updating? If the table does not have a primary key, the function won't have any primary ID to return.
Count Rows
Is it possible to count rows using COUNT?
$sql2 = "SELECT COUNT(*) FROM `MY_TABLE` WHERE `type` LIKE 'fun' "Answer
You can use a count() through a normal $db->query($sql2) or easier through query_first() like:
<?php$sql2 = "SELECT COUNT(*) AS amount FROM `MY_TABLE` WHERE `type` LIKE 'fun'";
$row = $db->query_first($sql2);
echo $row['amount'] ." rows of fun";
?>