How can I use a database schema in PHP? [closed] - php

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am writing a small PHP/MySQL application for personal use. This is my first time using PHP, so bear with me.
I wanted to be able to change the DB schema afterwards, if needed, so everything went into variables (stuff like table and column names). I used two approaches during development:
Global variables
db_schema.php:
$table = "table_name";
$column = "column_name";
main.php:
function do_db_stuff()
{
global $table;
global $column;
global $db;
$db->query("SELECT `$column_name` FROM `$table_name`;");
}
Defines
db_schema.php:
define (TABLE, "table_name");
define (COLUMN, "column_name");
main.php:
function do_db_stuff()
{
global $db;
$db->query("SELECT `" . COLUMN . "` FROM `" . TABLE . "`;");
}
Now, I like the nice syntax of the query string when I use variables - I do not need to use . concatentation, however this approach requires an unwieldy number of global statements at the beginning of each function. This was a dealbreaker. Approach number two does away with the globals, but the syntax is not so nice.
Is there a time-tried PHP-style solution to this problem?

What about this?
$schema = array(
'table' => 'spam',
'column' => 'eggs',
);
function do_db_stuff() {
global $db;
global $schema;
$sql = sprintf(
'SELECT `%s` FROM `%s`',
$schema['table'],
$schema['column']
);
$db->query( $sql );
}

I found the following solution which is pretty clean-looking:
db_schema.php
$table = "table";
$column = "column";
main.php
function do_stuff()
{
require "db_schema.php";
$db->query("SELECT `$column` FROM `$table`;");
}

I settled on the following solution which seems the most clean to me:
db_schema.php
$TABLE = "table";
$COL = "column";
main.php
function do_stuff
{
require 'db_schema.php';
$db->query("SELECT `$COL` FROM `$TABLE`;);
}

Related

Wordpress prepared LIKE query [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm trying to use a prepared LIKE query within Wordpress, but it doesn't seem to be working. I've followed the codex for the syntax.
public function userByJobId($id){
global $wpdb;
$result = $wpdb->get_row($wpdb->prepare( "SELECT * FROM use_users WHERE use_job_id LIKE = d%;", '%' . $wpdb->esc_like((int)$id)) . '%');
if(!empty($result)){
return $result;
}
return false;
}
Calling the method like so:
$userid = 1
$user = new Users();
$user_id = $user->userByJobId($userid);
Cant see where the issue lies..
A few points have been made already:
Syntax for prepare() is the same as that for sprintf; a decimal placeholder is %d, not d%
The LIKE keyword shouldn't be followed by an equals, just the expression to test against
A few other things:
You concatenate the LIKE % wildcard after the closing parenthesis for prepare(), where it should be concatenated before
get_row() will return an object by default, not just the ID, which is a property of the object returned
public function userByJobId($id){
global $wpdb;
$result = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}users WHERE {$wpdb->prefix}job_id LIKE %d;",
'%' . $wpdb->esc_like((int)$id) . '%'
)
);
if($result){
return $result->ID;
}
return false;
}
The wordpress class reference tells me that:
Possible format values: %s as string; %d as integer (whole number);
and %f as float.
When you want to prepare a query with a like comparison you should double escape percentages.
So change
$result = $wpdb->get_row($wpdb->prepare( "SELECT * FROM use_users WHERE use_job_id LIKE = d%;", '%' . $wpdb->esc_like((int)$id)) . '%');
To
$result = $wpdb->get_row($wpdb->prepare( "SELECT * FROM use_users WHERE use_job_id LIKE %%%d%%;",(int)$id));
You also don't have to escape values (the prepare method does that for you).
Warning: Non tested code

Using database class with PDO [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
The classic first liner - have seen similar questions on SO but none that truly help me understand the crossroads I am at.
A little background before the code - I am not new to PHP or PDO (though not an expert either), but am a complete newbie to Object Oriented PHP and am trying to get the balance right of when to use classes and when it is possibly overkill.
The answer I'm hoping is in two parts. Firstly, it is good practice to create a wrapper database class when using PDO - for connection, basic queries etc.
Secondly, if not - are there better ways to speed up query writing?
EDIT Whilst I am questioning the code below, really I am question the PDO wrapper class approach overall - so the class below could be much larger than this, but is there any need/benefit?
See the following code;
NOTE: The class file is called via spl_autoload_register() in config.php
class_database.php
class Database
{
private $conn;
public function __construct() {
$this->openConnection();
}
public function openConnection() {
try {
$this->conn = new PDO('mysql:host=' . DB_SERVER . '; dbname=' . DB_NAME, DB_USER, DB_PASS);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'There was an error connecting to the database, Error: ' . $e->getMessage();
die();
}
}
public function getAll($sql, array $params) {
$stmt = $this->conn->prepare($sql);
$stmt->execute($params);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
generic_file.php
require_once '../includes/config.php';
$dbh = new Database();
$sql = ("SELECT * FROM users where id = :id and username = :username");
$id = 1;
$username = 'craig';
$params = array(':id' => $id,
':username' => $username);
$row = $dbh->getAll($sql, $params);
var_dump($row);
Now, to me this seems totally pointless. Using PDO alone, not a wrapper class, this query would be just as simple to write. On top of this - what if I want to use different fetch methods - I'd have to write more methods in the class.
Also, previously I have used a simple function to instantiate and return a new PDO object, simply including that file and assigning a variable to the function return was simple as quick - again I feel the class method is overkill.
Also, with my code above, and by doing this in a class, am I not losing the benefit of 'preparing' the statement as I will have to pass the sql statement in each time, even just to change the variables for the same statement?
However, I find lots of examples online, and especially on Lynda.com which I am using currently, of database wrapper classes. On top of this - I am no expert, and therefore what I feel is overkill may actually be best practice and strongly recommended, hence looking to you SO experts to help me out!
So...back to my question - is there a good reason to use such a class when using PDO?
If not, is there another DRY method that others use to minimize lines of codes needed for queries using PDO?
Thanks in advance.
I had your same question at one time.
The benefit to abstracting the database away is you can assure all connections are made correctly and if you ever do need to change the type of database there is only one spot that you need to change the code for. It also makes it easier to check the queries issued because you know if you echo and exit in the class all of the queries will able to be checked.
The way I solved it was by creating a class where the constructer established the connection and assigned it to a private variable while also setting the table in the database too.
The best way is to then have a few public functions to create, retrieve, update, and delete. Which is sometimes called CRUD.
For each function the only and first parameter is an array. For creating it takes the array and creates a prepared statement with it and then executes it.
It does a very similar thing with the others but for retrieve the array is what is being matched, for update it takes the things ending in id and sets the rest to update where the id = provided, and for delete it deletes where all of the keys = value in the table.
EDIT:
Here is the delete function I put in the class. If one of the parameter's values is an array it will prepare the statement and cycle through it. That is only for one variable changing though. You could also have it where you pass an array with the values of the numerical indexes being an array of what you would want to insert though that is not how I set up my code.
public function delete($info) {
$dbh = $this->dbh;
if (isset($info['submit_action'])) unset($info['submit_action']);
$where = array();
foreach (array_keys($info) as $name) {
$where[] .= "$name = :$name";
}
//echo "DELETE FROM {$this->table_name} WHERE " . implode(" AND ", $where) . ";"; exit;
$data = $dbh->prepare("DELETE FROM {$this->table_name} WHERE " . implode(" AND ", $where) . ";");
foreach ($info as $name => $value) {
if ($array_value == $name) $data->bindParam(":$name", $array_info);
else $data->bindValue(":$name", trim($value));
}
foreach ($info as $name => $value) if (is_array($value)) { $array_value = $name; break; }
if (isset($array_value)) {
foreach ($info[$array_value] as $array_info) {
try {
$data->execute();
}
catch (PDOException $e) {
if (!is_null($this->error_msg))
handle_error($this->error_msg, $e->getMessage());
else
handle_error("There was a problem removing the {$this->subject}.", $e->getMessage());
}
}
} else {
try {
$data->execute();
}
catch (PDOException $e) {
handle_error(/*public error msg - could set this anyway you want*/, $e->getMessage());
}
}
// Send success msg
}

Calling PDO inside a Function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am following a project for creating spell checker. However, rather than using regular mysql, i decided to go with PDO. So i converted code to PDO. I am stuck at one point and not sure why i can't call PDO inside any function even after declaring global variable. What i am doing wrong?
Purpose: I have loaded 100k+ words in a table and want to find similar words by searching one word.
<?php
include "db.inc.php";
function spellcheck($word){
global $db;
$output = array();
$word = $db->quote($word);
$words = $db->prepare("SELECT words FROM english WHERE SUBSTRING(word, 0, 1) = '.substr ($word, 1, 2)'");
$words->execute();
while (($words_row = $words->fetch(PDO::FETCH_ASSOC)) !== false){
echo $words_row['word'];
}
}
if (isset($_GET["word"]) && trim($_GET["word"]) !== null){
$word = $_GET["word"];
$spellcheck = spellcheck($word);
}
?>
<form action="" method="GET">
Please type word to check: <input type="text" name="word">
<input type="submit" value="Check">
</form>
Try the following:
function spellcheck($word){
$db = new PDO ("mysql:host=localhost;dbname=splcheck", "root", "");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$query = "SELECT words FROM english WHERE SUBSTRING(word, 0, 1) = :word";
$stmt = $db->prepare($query);
$stmt->execute(array(':word'=> substr ($word, 1, 2)));
$output = array();
while ($words_row = $stmt->fetch(PDO::FETCH_ASSOC)){
$output[] = $words_row['words'];
}
return $output;
}
Don't use global, pass the connection as argument instead
Make sure you prepare your query properly
Your function was not returning the output
Remove !== false from the while loop its redudant
Avoid typos you forgot s on $words_row['words'];
Using like statement:
$query = "SELECT `words` FROM english WHERE `word` = LIKE :word";
$stmt = $db->prepare($query);
$stmt->execute(array(':word'=>'%'.$word.'%'));

PHP MySQL query not working using my DB class [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I've set up a Database class, a User class and a UserTools class to interact with a MySQL database. It seems that my UPDATE, DELETE and INSERT commands are working find but I can't figure out what's going on with my SELECT statements. I'm only using mysql right not until I get everything working as I'd like, then I'll switch over to mysqli or PDO. But anyway, here's what I'm looking at....
DB class....
public function select($table, $where) {
$sql = "SELECT * FROM $table WHERE $where";
$result = mysql_query($sql);
if (mysql_num_rows($result) == 1)
return $this->processRowSet($result, true);
return $this->processRowSet($result);
}
public function processsRowSet($rowSet, $singleRow=false) {
$resultArray = array();
while ($row = mysql_fetch_assoc($rowSet)) {
array_push($resultArray, $row);
}
if ($single_row === true)
return $resultArray[0];
return $resultArray;
}
UserTools class
public function getUser($id) {
$db = new DB();
$result = $db->select('users', 'id = $id');
return new User($result);
}
There seems to be an issue with how I'm processing the rows or something. I've followed similar setups with UPDATE,DELETE,INSERT and they seem to work fine but I don't know whats going on here.
If I call an instance of new UserTools(), then try to run the getUser() function, it's not returning anything the way it's set up. If I keep the result from being pushed through the User class constructor, it just returns a Reference Value, meaning that I'm not processing the rows properly.
I have a feeling I'm overlooking something stupid here so any help would be greatly appreciated. Thanks!
For a start,
$result = $db->select('users', 'id = $id');
Should be
$result = $db->select('users', 'id = '.$id);
As Casimir mentioned, there's a typo in public function processsRowSet
I'd echo $sql; die; to check if the query is complete.
In UserTools class: 'id = $id' wouldn't parse in $id. Instead do "id = {$id}" or similar so that it can parse $id.

query function breaks mysteriously [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have a Database class which has multiple functions to execute queries. One of them is the simplest of them all:
public function query($query) {
return $this->_link->query($query);
}
$this->_link->query works in other cases, so it should work here. From a file that has an instance of a class, I do this:
function createLineChart() {
$query = "select * from tags";
$result = $db->query($query);
// do something with result
}
createLineChart();
but it breaks on the $result line. The query is also valid, I've testid it. Am I missing something?
Your problem is $db is out of scope of the createLineChart() function. You can either use the global method:
function createLineChart() {
global $db; // <-- make the db var become available
$query = "select * from tags";
$result = $db->query($query);
// do something with result
}
Or pass the $db object to the function as an argument:
function createLineChart($db) {
$query = "select * from tags";
$result = $db->query($query);
// do something with result
}
createLineChart($db);
More info about Variable Scope on the Manual.
function createLineChart() {
var_dump($db);
// this should probably return 'undefined'
global $db;
// so globalize it!
$query = "select * from tags";
$result = $db->query($query);
// do something with result
}
If $db is a class variable, then you need to refer it as:
$result = $this->db->query($query);

Categories