Check if table exist using PDO - php

Hello all decided to begin learning PDO. However i'm having trouble creating a function to check if a table exists in my db.
Each individual item has there own table in which the table name is ($id).
<?php
include_once('config.php');
include_once('simple_html_dom.php');
$html = file_get_html('http://localhost:8888/CDOnline%20Online.html');
foreach($html->find('div.product-stamp-inner') as $content) {
$detail['itemid'] = $content->find('a',0)->href;
$detail['itemid'] = substr($detail['itemid'], 40, 6);
if (strpos($detail['itemid'], "?") !== false) {
$detail['itemid'] = substr($detail['itemid'], 0, 5);
}
$id = $detail['itemid'];
tableExists($dbh, $id);
}
function tableExists($dbh, $id)
{
//check if table exists
}
$dbh = null;
?>
I've tried to scour the forums in search of an answer but came up empty handed. The only thing that got me close to my answer was:
function tableExists($dbh, $id)
{
$results = $dbh->query("SHOW TABLE LIKE `$id`");
if(count($results)>0){echo 'table exists';}
}
But that just says all tables exists, when half of the tables don't exist.
Edit:The table should exist if there is 1 or more rows.

You are using backtics around $id. Change it to single quotes. Like this:
"SHOW TABLES LIKE '$id'"
Further note that the statement count($results)>0 will not work. You'll have to use $results->rowCount() instead.
Fxing both errors will give you the following function:
function tableExists($dbh, $id)
{
$results = $dbh->query("SHOW TABLES LIKE '$id'");
if(!$results) {
die(print_r($dbh->errorInfo(), TRUE));
}
if($results->rowCount()>0){echo 'table exists';}
}

SHOW TABLES... is MySQL dialect and will fail under pretty much any other DB engine. This is certainly not the definitive answer to portable table detection.
The closest to portable you could get would be to check whether SELECT * FROM $table yields an error,
or similar methods discussed here
If your need is simply to create a table if it does not exist, you can use:
CREATE TABLE IF NOT EXISTS $table ($field, ...)
You might want to name your tables in lower case to work around this bug if your DB is located on a Windows MySQL server, though.

This is posted simply if anyone comes looking for this question. Even though its been answered a bit.
if ($con->query(
"SHOW TABLES LIKE '" . $table . "'"
)->rowCount() > 0
or die("No table set")
){
With this I just push the else condition into or. And for my needs I only simply need die. Though you can set or to other things. Some might prefer the if / else if / else. Which is then to remove or and then supply if / else if / else.
Or if I was to redo the function:
function tableExists($dbh, $id){
if ($dbh->query(
"SHOW TABLES LIKE '" . $id . "'"
)->rowCount() > 0
or die(print_r($dbh->errorInfo(), TRUE))
){
echo 'table exists';
}
}
Did not test the redo, though it should work the same as the code I have used before. Just in function.

This seems like the simplest way to do this. You pass this function an array with the pdo object you have already created.
$db['pdo']=new PDO('mysqlconnectiongoeshere');
$db['table']='tabletobechecked';
function is_table($db){
$is_table=$db['pdo']->query("SHOW TABLES LIKE '".$db['table']."'");
return$is_table->rowCount();
}
This way if the table exists this function returns a '1' and if it doesn't exist this function returns a '0';
So you can use it like this:
if(is_table($db)){
echo"The table".$db['table']." exists.";
}else{
echo"The table".$db['table']." does not exist.";
}

private function doesTableExist($table)
{
try {
$this->db->query("DESC $table");
} catch (Exception $e) {
return false;
}
return true;
}

Just use good old row count. There must be a result if table exist.
$sql ="SELECT count(*) FROM [table name]";
$sql_result = $this->db_mssql->prepare($sql);
$sql_result->execute();
$sql_result->setFetchMode(PDO::FETCH_ASSOC);
$my_res = $sql_result->fetchAll();
if($my_res){
echo 'table exists';
}

Related

How do I find if a column exists or not using PHP + mysqli database

How do I find if a column exists or not using PHP + mysqli database.
I've been trying these and also comment part..but nothing seems to be working.
$column1="address";
$chkcol="SELECT * FROM `table_name` LIMIT 1";
/* $chktable="SELECT * FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = `db_name` AND TABLE_NAME = `table_name` AND COLUMN_NAME = `$col_name`";*/
$mycol = mysqli_fetch_array($chkcol);
/* echo $val=mysqli_query($conn,$chktable);
echo $val; */
if(isset($mycol['$column1']))
{
$message="Adress column already exists.";
echo $message;
}
else
{
echo "Column doesn't exist";
}
If there's any shortcode or simple code to make it work. Then let me know.
This isn't MySQL, it's MySQLi(Procedural), since the earlier answers I found were MySQL (Obj Oriented) does't work.
Assuming you have already created the DB/Table with all the fields and successfully established connection with the MySQL database you're using (by creating a mysqli object or the procedural way), which might look something like this -
$connection = new mysqli('HOST_NAME', 'USERNAME', 'PASSWORD', 'DATABASE_NAME');
Write down your SQL query this way and store it in the variable of your choice. This way -
$query = 'SHOW COLUMNS FROM table_name';
Issue the query to the DB in the following way and capture the result -
$result = $connection->query($query);
You can then use the fetch_all function with a MYSQLI_ASSOC constant to retrieve all the column names. This way -
$values = $result->fetch_all(MYSQLI_ASSOC);
$column_names = array(); // $column_names = [];
if(!empty($values)){
$column_names = array_keys($values[0]);
}
Now you know the column name you're looking for, which is stored as
$column1 = "address";
You can now check the $column_names array if your column exists -
if (in_array($coulmn1, $column_names)) {
echo "Yes! " . $column1 . " is present in the table!";
}
This is a slightly longer solution. Probably not what you were looking for, but hope this helps.

Creating a dynamic MySQL query from URL paramaters

I am really trying to wrap my head around this and failing miserably. What I want to do it build a MySQL query based on the URL parameters passed by the URL. I am trying to create a re usable dynamic script that can do what it needs to do based on the URL parameter.
This is what I have come up with, and it appears that it does what it is supposed to do (no errors or anything) but nothing actually gets inserted in the database. I know somewhere I have made a dumb mistake (or thought something out wrong) so hopefully one of you guys can point me in the right direction.
Thanks!
//List all possible variables you can expect the script to receive.
$expectedVars = array('name', 'email', 'score', 'age', 'date');
// This is used for the second part of the query (WHERE, VALUES, ETC)
$fields = array('uName','uEmail','uScore','uAge','uDate');
// Make sure some fields are actually populated....
foreach ($expectedVars as $Var)
{
if (!empty($_GET[$Var]))
{
$fields[] = sprintf("'%s' = '%s'", $Var, mysql_real_escape_string($_GET[$Var]));
}
}
if (count($fields) > 0)
{
// Construct the WHERE Clause
$whereClause = "VALUES " . implode(",",$fields);
//Create the SQL query itself
$sql = ("INSERT INTO $mysql_table ($fields) . $whereClause ");
echo "1"; //It worked
mysql_close($con);
}
else
{
// Return 0 if query failed.
echo "0";
}
?>
You missed mysql_query($sql):
if(!mysql_query($sql)){
//die(mysql_error());
}
Please consider to use PDO or My SQLi using parametrize query because mysl_* function depreciated.
Your SQL is all wrong. You're using the field = value syntax for an INSERT, then you're concatenating an array as if it were a string ($fields), and you're missing a couple of parentheses around the values.
a couple of things: i've found for php <-> mysql its important to see what's going into mysql and experiement directly with those queries in phpmyadmin when i get stuck.
1 - in my code I output mysql_error() when the query fails or when a debug flag is set. this usually explains the sql issue in a way that can point me to a misspelled field name etc...
2 - this way i can feed that mysql query directly into phpmyadmin and tweak it until it gives me the results i want. (while i'm there i can also use explain to see if i need to optimize the table)
specifics in your code. unlike C languages sprintf is implied. here's how i'd write your code:
// List all possible variables you can expect the script to receive.
$expectedvars = array('name', 'email', 'score', 'age', 'date');
// This is used for the second part of the query (WHERE, VALUES, ETC)
// $fields = array('uName','uEmail','uScore','uAge','uDate');
$fields = array();
// Set only the variables that were populated ...
foreach ($expectedvars as $var) {
if (!empty($_GET[$var])) {
$name = "u" + ucwords($var); // convert var into mysql field names
$fields[] = "{$name} = " . mysql_real_escape_string($_GET[$var]);
}
}
// only set those fields which are passed in, let the rest use the mysql default
if (count($fields) > 0) {
// Create the SQL query itself
$sql = "INSERT INTO {$mysql_table} SET " . implode("," , $fields);
$ret = mysql_query($sql);
if (!$ret) {
var_dump('query_failed: ', $sql, $ret);
echo "0"; // Query failed
} else {
echo "1"; // It worked
}
} else {
// Return 0 if nothing to do
echo "0";
}
mysql_close($con);

Basic mysqli select

I have a select statement where I want to get all rows from a table but seem to be having a mental blockage - this should be elementary stuff but can't seem to get it working.
There are only two rows in the table 'postage_price' - and two columns : price | ref
Select statement is as follows:
$get_postage="SELECT price FROM postage_price ORDER BY ref DESC";
$get_postage_result=mysqli_query($dbc, $get_postage) or die("Could not get postage");
while($post_row=mysqli_fetch_array($dbc, $get_postage_result))
{
$post1[]=$post_row;
}
I am then trying to echo the results out:
echo $post1['0'];
echo $post1['1'];
this is not showing anything. My headache doesn't help either.
while($post_row = mysqli_fetch_array($dbc, $get_postage_result))
{
$post1[] = $post_row['price'];
}
As you see: $post_row in this line: = mysqli_fetch_array($dbc, $get_postage_result) is an array. You are trying to save the whole array value to another array in a block. :)
EDIT
while($post_row = mysqli_fetch_array($get_postage_result))
...
You have $post1[]=$post_row; and $post_row is itself an array. So you can access post data with following: $post1[NUMBER][0] where NUMBER is a $post1 array index and [0] is 0-index of $post_row returned by mysqli_fetch_array.
Probably you wanted to use $post1[]=$post_row[0]; in your code to avoid having array of arrays.
You are passing 1 and 0 as string indexes, this would only work if you had a column called 0 or 1 in you database. You need to pass them as numeric indexes.
Try:
print_r($post1[0]);
print_r($post1[1]);
or
print_r($post['price']);
print_r($post['ref']);
with all your help I have found the error - it is in the mysqli_fetch_array where I had the $dbc which is not required.
$get_postage="SELECT price FROM postage_price ORDER BY ref DESC";
$get_postage_result=mysqli_query($dbc, $get_postage) or die("Could not get postage");
while($post_row=mysqli_fetch_array($get_postage_result))
{
$post1[]=$post_row['price'];
}
instead of:
$get_postage="SELECT price FROM postage_price ORDER BY ref DESC";
$get_postage_result=mysqli_query($dbc, $get_postage) or die("Could not get postage");
while($post_row=mysqli_fetch_array($dbc, $get_postage_result))
{
$post1[]=$post_row['price'];
}
Bad day for me :(
Thanks all
If something does not work in a PHP script, first thing you can do is to gain more knowledge. You have written that
echo $post1['0'];
echo $post1['1'];
Is showing nothing. That could only be the case if those values are NULL, FALSE or an empty string.
So next step would be to either look into $post1 first
var_dump($post1);
by dumping the variable.
The other step is that you enable error display and reporting to the highest level on top of your script so you get into the know where potential issues are:
ini_set('display_errors', 1); error_reporting(~0);
Also you could use PHP 5.4 (the first part works with the old current PHP 5.3 as well, the foreach does not but you could make query() return something that does) and simplify your script a little, like so:
class MyDB extends mysqli
{
private $throwOnError = true; # That is the die() style you do.
public function query($query, $resultmode = MYSQLI_STORE_RESULT) {
$result = parent::query($query, $resultmode);
if (!$result && $this->throwOnError) {
throw new RuntimeException(sprintf('Query "%s" failed: (#%d) %s', $query, $this->errno, $this->error));
}
return $result;
}
}
$connection = new MyDB('localhost', 'testuser', 'test', 'test');
$query = 'SELECT `option` FROM config';
$result = $connection->query($query);
foreach ($result as $row) {
var_dump($row);
}

Simple PHP SQLite question

I am trying to implement a function that will insert a new entry in a database if a field with same name (as the one given) doesn't already exist. In particular I want to restrict duplicate usernames in a table.
The only way I could think was to run a select query and then if that doesn't return anything run the insert query. For some reason though I cant get it to work...
My db select Function
function getAllUsers($user)
{
$stmt = $this->db->stmt_init();
$stmt->prepare('SELECT username from users where username=? ');
$stmt->bind_param("s", $user);
$stmt->bind_result($username);
$stmt->execute();
$results = array();
while($stmt->fetch())
{
$results[] = array('username' => $username);
}
$stmt->close();
return $results;
}
My php code (this is in a different page)
foreach ($GLOBALS['db']->getAllUsers($_POST['username']) as $i)
{
$results = "".$i['username']."";
break;
}
if(strcmp($results, "")==0)
{
if($GLOBALS['db']->addUser($_POST['username'],$_POST['password']))
{
session_destroy();
echo "registerSucces";
}
else
{
session_destroy();
echo "registerError";
}
}
else
{
echo "userNameExists";
}
Can you see whats wrong with this???
Thanks
Mike
Still cant find how to make the above code work but just in case someone needs this: A temporary simple solution is not to compare strings at all and instead have a counter in the foreach loop and then check that upon a desired number(0 in my case)...
SQLite supports the UNIQUE constraint. Simply declare a UNIQUE index on the column and check whether an INSERT fails.
If you're using the username as the primary key in your tables, you can use the INSERT OR IGNORE command instead of checking to see if the username already exists.
If SQLite finds that an INSERT OR IGNORE command will conflict with an existing row in your table, it will simply ignore the command.
You can find out more stuff in the SQLite documentation for the INSERT command

What is a good wrapper/framework/libraries for dealing with interface PHP applications to an SQL database?

I have a table
$query=
"CREATE TABLE screenshot ".
"(screenshot_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, ".
"source_video_id INT UNSIGNED NOT NULL, ".
"screenshot_file_name VARCHAR(128), ".
"x_res INT, ".
"y_res INT, ".
"time INT UNSIGNED);";
mysql_query($query);
Then I insert things into that table.
I often want to do an SQL query and iterate over the result of the query, but end up doing this.
//select all screenshots from video, by video id
$q0=
"SELECT * FROM screenshot ".
"WHERE source_video_id = '$source_video_id' ".
"AND x_res = 120 ".
"AND y_res = 90 ".
"ORDER BY time ASC;";
$r0 = mysql_query($q0);
$n0_num = mysql_numrows($r0);
//for each result
for($n0=0;$n0<$n0_num;$n0++) {
$source_video_id = mysql_result($r0,$n0,'source_video_id');
$time = mysql_result($r0,$n0,'time');
$screenshot_file_name = mysql_result($r0,$n0,'screenshot_file_name');
//do stuff for each returned result!
}
This is just ugly. To get the SQL query results, I have to write this for every column!
$source_video_id = mysql_result($r0,$n0,'source_video_id');
I have to write an ugly loop, get the results for each row returned and do something for each result. Basically I want something like;
foreach($SQL_command) {
//Do for each result
}
I want the column variables for each row to be already set, so that I do not have to do
$source_video_id = mysql_result($r0,$n0,'source_video_id');
For each and every column I want to access!
I am sick of writing boiler plate code to do this for every single table in my data. Are there any frameworks or libraries that would make this less painful?
These are the very basics of a database abstraction layer. It's not hard to program your own, or you can use a generic library like Doctrine or Propel. Every notable PHP framework includes some form of database abstraction as well, you really just need to start using one.
One can suppose I'm a fan of Kohana, but I really love the thing. Get the Kohana 3 and put there the Sprig ORM (it's a fork from original Sprig ORM, but with additional ‘sugar’ :) instead of native Kohana's one. You'll understand how pretty they are together. You'll can access to your tables like this code shows:
//just the basics, updating existing record
$screenshot = Sprig::factory('Screenshot', $id)->load();
$screenshot->x_res = 240;
$screenshot->y_res = 260;
$screenshot->update();
//creating new one
$screenshot = Sprig::factory('Screenshot');
$screenshot->x_res = 300;
$screenshot->y_res = 250;
$screenshot->create();
Additional link to the discussion of the Sprig fork: http://forum.kohanaframework.org/comments.php?DiscussionID=4368
Hope, it'll help you.
If you have the PDO drivers enabled (as you should) you can use the single DB() method as a function from the phunction PHP framework. It was inspired by the DiBi database abstraction layer. The documentation is still underway, but I've posted a short summary in this answer.
function DB($query)
{
static $db = null;
static $result = array();
if (is_null($db) === true)
{
if (preg_match('~^(?:mysql|pgsql):~', $query) > 0)
{
$db = new PDO(preg_replace('~^(mysql|pgsql):(?:/{2})?([-.\w]+)(?::(\d+))?/(\w+)/?$~', '$1:host=$2;port=$3;dbname=$4', $query), func_get_arg(1), func_get_arg(2));
if (preg_match('~^mysql:~', $query) > 0)
{
self::DB('SET time_zone = ?;', 'GMT');
self::DB('SET NAMES ? COLLATE ?;', 'utf8', 'utf8_unicode_ci');
}
}
else if (preg_match('~^(?:sqlite|firebird):~', $query) > 0)
{
$db = new PDO(preg_replace('~^(sqlite|firebird):(?:/{2})?(.+)$~', '$1:$2', $query));
}
}
else if (is_a($db, 'PDO') === true)
{
if (isset($query) === true)
{
$hash = md5($query);
if (empty($result[$hash]) === true)
{
$result[$hash] = $db->prepare($query);
}
if (is_a($result[$hash], 'PDOStatement') === true)
{
if ($result[$hash]->execute(array_slice(func_get_args(), 1)) === true)
{
if (preg_match('~^(?:INSERT|REPLACE)~i', $query) > 0)
{
return $db->lastInsertId();
}
else if (preg_match('~^(?:UPDATE|DELETE)~i', $query) > 0)
{
return $result[$hash]->rowCount();
}
else if (preg_match('~^(?:SELECT|EXPLAIN)~i', $query) > 0)
{
return $result[$hash]->fetchAll(PDO::FETCH_ASSOC);
}
return true;
}
}
return false;
}
}
return $db;
}
Your example query could be written as:
// connect to the MySQL server, do this on your config file or something
DB('mysql://host:port/database_name/', 'username', 'password');
// run the query!
$results = DB('SELECT * FROM screenshot WHERE source_video_id = ? AND x_res = ? AND y_res = ? ORDER BY time ASC;', $source_video_id, 120, 90);
foreach ($results as $result)
{
print_r($result);
}
The above code uses prepared queries which means that you'll also be safe from SQL injection attacks.
PS: I'm biased here, since I'm the developer of the framework. If you run into any problems let me know.
I use RedBean in all my projects and would recommend it without hesitation. The main reasons being:
Minimum configuration required. I don't have to map the database schema into a YAML or JSON file, simply put in the connection parameters and go.
Elegant and easy to understand usage syntax.
Lots of features such as caching and tree relationships.
Pretty good performance.
And here's an example of using it:
$book = R::dispense('book');
$book->title = 'Gifted Programmers';
$book->author = 'Charles Xavier';
$id = R::store($book);

Categories