PHP / MySQL Need a Database Class - php

I need some help. I am working on a project and I found myself writing a bunch of functions for grabbing information from the database:
For Example:
function getSlideByUserAndSortId($sort_order) {
global $mysqli;
global $user_id;
if ($stmt = $mysqli->prepare("SELECT slide_id FROM user_slides WHERE user_id = ? AND sort_order = ?")) {
$stmt->bind_param('ii', $user_id, $sort_order);
$stmt->execute();
$stmt->bind_result($returnSlideId);
$stmt->store_result();
$stmt->fetch();
return $returnSlideId;
$stmt->close();
}
}
function getSlideText($var) {
global $mysqli;
global $user_id;
global $current_slide;
if ($stmt = $mysqli->prepare("SELECT text FROM slide_data WHERE slide_id = ? AND user_id = ? LIMIT 1")) {
$stmt->bind_param('ii', $current_slide, $user_id);
$stmt->execute();
$stmt->bind_result($text);
$stmt->store_result();
$stmt->fetch();
$text = ($stmt->num_rows < 1 ? $var : $text);
return $text;
$stmt->close();
}
}
Which is so messy.. What I need is a class like Codeigniter where I can just do:
$this->db->select('*');
$this->db->from('blogs');
$this->db->join('comments', 'comments.id = blogs.id');
$query = $this->db->get();
How does everyone else do it? If you have a lot of information you need to grab and a lot of queries, what is the best way to display the data?

What you're looking for is an Object Relational Mapper and there have been many created for use with PHP and MySql. Some of the best and most widely used are Propel and Doctrine
However you cand find many other suggestions on this stackoverflow question

Related

Property access is not allowed yet in

I have one simple function for delete account from my database. I have written it like below
public function removeAccount($email) {
$response = array('code' => 0, 'error' => false);
$stmt = $this->conn->prepare("SELECT id FROM user WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows) {
$user = $result->fetch_assoc();
$id = $user['id'];
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM number_list WHERE user_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM number_status WHERE user_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("INSERT INTO old_user(email,serial,premium) SELECT email, device_id, membership FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $this->conn->prepare("DELETE FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
if ($stmt->affected_rows) {
$response["code"] = 1;
}
}
return $response;
}
Its giving me warning in below line
if ($stmt->affected_rows) {
I have searched way for solve it but does not getting idea whats wrong and what can fix it. Please check and let me know if someone can have idea about it. Thanks a lot.
$stmt = $this->conn->prepare("DELETE FROM user WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
if($stmt->affected_rows > 0) { $response["code"] = 1; }
$stmt->close();
In this case, we checked to see if any rows got updated. For reference, here's the usage for mysqli::$affected_rows return values.
-1 - query returned an error; redundant if there is already error handling for execute()
0 - no records updated on UPDATE, no rows matched the WHERE clause or no query has been executed
Greater than 0 - returns number of rows affected; comparable to mysqli_result::$num_rows for SELECT
You're trying to get the number of affected rows from a closed statement.
Instead of
$stmt->execute();
$stmt->close();
if ($stmt->affected_rows) {
$response["code"] = 1;
}
Use
$stmt->execute();
$num_affected_rows = $stmt->affected_rows;
$stmt->close();
if ($num_affected_rows) {
$response["code"] = 1;
}
There are many reasons for this error, but the one I had today was one I have not found documented anywhere.
I had two (2) copies of same virtual machine running and they were both competing in some way that I do not understand well enough to explain, but going into VirtualBox and shutting one of them off solved the problem.
I know this an obscure scenario, but if anyone else runs across the same I hope my answer stops them from wasting time on it like I did.

PHP/MySQL SET var = var - var

I made a shop for my site, and got it working but realized it was lacking the ability to properly buy an item. to put it into perspective, you don't walk into a store, grab an item, buy it, grab it again, buy it, grab it again, etc. to get as many as you want. you grab them all at once. my site is lacking such feature. So, I have attempted to change the code that takes the stock, and so far am not succeeding.
I've tried the following:
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - ?
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
and
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - $count
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
and
function takestock($id, $count) {
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."shop
SET stock = stock - ".$count."
WHERE
id = ?");
$stmt->bind_param("ii", $id, $count);
$result = $stmt->execute();
$stmt->close();
return $result;}
but I cant seem to take the count away from the stock!
The order that you bind parameters should correspond to the order you want to use them in your SQL statement. Here, the item count should come first and the id second. I.e., replace the following line:
$stmt->bind_param("ii", $id, $count);
With:
$stmt->bind_param("ii", $count, $id);

Converting mysql functions to mysqli prepared statment keeping the same output

I'm currently going thorough a site and replacing all the functions which used to return mysql_fectch_array() results, which are put into while loops elsewhere. I'm trying to make them return the same data in the same format but by using mysqli prepared statements output. I have been successful with the code below in producing the same formatted output for single row results.
public function get_email_settings(){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT * FROM email_setting WHERE user_id = ? LIMIT 1");
$stmt->bind_param("i", $this->user);
$stmt->execute();
$stmt->bind_result(
$row['email_id'],
$row['user_id'],
$row['news'],
$row['new_message'],
$row['new_friend'],
$row['rule_assent'],
$row['agreement_ready'],
$row['agreement_all_assent'],
$row['time_cap'],
$row['donations']
);
$stmt->store_result();
$stmt->fetch();
$stmt->close();
return $row;
}
But how can I get this code to work when it returns more than one row? I want it to be produce the same result as if I had written:
return mysql_fetch_array($result);
Is it possible?
Consider the following adjustment, passing query results into an associative array:
public function get_email_settings(){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT email_id, user_id, news, new_message,
new_friend, rule_assent, agreement_ready,
agreement_all_assent, time_cap, donations
FROM email_setting
WHERE user_id = ? ");
$stmt->bind_param("i", $this->user);
$stmt->execute();
// CREATE RETURN ARRAY
$row = [];
// OBTAIN QUERY RESULTS
$result = $stmt->get_result();
// ITERATE THROUGH RESULT ROWS INTO RETURN ARRAY
while ($data = $stmt->fetch_assoc()) {
$row[] = $data;
}
$stmt->close();
return $row;
}
You will notice I explicitly select the query's fields to avoid an indeterminate loop through query results.
Ok I have managed to get it to work without using get_result()
This is how I did it with alot of help from Parfait and Example of how to use bind_result vs get_result
function saved_rules($user){
$stmt = $this->cn->stmt_init();
$stmt->prepare("SELECT R.rule_id, R.rule_title
FROM Savedrules S
LEFT JOIN Rule R
ON S.saved_rule_id = R.rule_id
WHERE S.saved_user_id = ?");
$stmt->bind_param("i", $user);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $rule_title);
while ($stmt->fetch()) {
$result[] = Array("rule_id"=>$id,"rule_title"=>$rule_title);
}
$stmt->free_result();
$stmt->close();
return $result;
}
Its not exactly the same output as using a mysql_fetch_array() so where it is used I have to change the loop to:
foreach($saved_rules AS $row){}
from
while ($row = mysql_fetch_array($saved_rules){}

Proper way to pass %like% param with PDO?

Here's the query below,
public function getSearchResult($searchString){
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("i", "%".$searchString."%");
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
Error I am getting is
Fatal error: Cannot pass parameter 2 by reference in
I guess I am doing the like param incorrectly (as it works for where = condition). I am pretty new to slim, any help?
You have to form the string before you can use it in bind_param()
public function getSearchResult($searchString){
$search = '%'. $searchString . '%';
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("s", $search);
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
In addition it looks like you're passing a string, not an integer, make sure you set the type to "s"
You need to set where your i variable goes.
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name LIKE :i ");
$stmt->bind_param(":i", "%$searchString%", PDO::PARAM_STR);
Here is an example in php.net
<?php
public function getSearchResult($searchString){
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("s", "%$searchString%",PDO::PARAM_STR);
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
Search string in where condition so it would be s and add PDO::PARAM_STR

fetch() not returning first row

I am trying to update code that has been written using prepared statements. This is my first time using them and I am having difficulty retrieving all the results. When I use a direct SQL statement, it works so I don't think that's the problem.
The code will not return any results until there are at least two that match the query, then it will return all but the first row. I tried using fetchAll, but that gives different error about a call to an undefined method.
Thanks in advance for any help that you can provide. If it's not to much to ask, please provide example or reference I can refer to and complete my understanding.
function html_competitive_make_gallery ($init) {
global $USER;
$user_id = $USER->id;
$page_name = 'competitive';
$base_name = $init['base_name'];
global $link;
$sql_pre = "SELECT form_id, community_id FROM frm_root WHERE user_id = ?
AND page_name = ? ORDER BY last_modified_date DESC LIMIT 1";
$stmt = $link->prepare($sql_pre);
$stmt->bind_param('is', $user_id, $page_name);
$stmt->execute();
$stmt->bind_result($form_id,$community_id);
$stmt->fetch();
$stmt->close();
$sql = "SELECT data FROM tester WHERE type= '".$base_name."'
AND form_id= '".$form_id ."' AND community_id= '". $community_id ."' LIMIT 5";
$stmt = $link->prepare($sql);
$stmt->execute();
$stmt->bind_result($data);
$stmt->fetch();
$html[]='<div class="gallery" style ="width:100%;height:30%;overflow:hidden;">';
while ($stmt->fetch()){
echo $data;
}
$stmt->close();
$html[]='</div>';
return implode ( $html);
}
You're running fetch() before entering your loop, hence dropping the first row of your results:
$stmt->execute();
$stmt->bind_result($data);
$stmt->fetch(); // <<< THIS LINE SHOULD NOT BE HERE
$html[]='<div class="gallery" style ="width:100%;height:30%;overflow:hidden;">';
while ($stmt->fetch()){
echo $data;
}
$stmt->close();
Try this:
while ($data = $stmt->fetch()){
echo $data;
}
$stmt->close();
Your main problem is called "mysqli".
You will face such problems as long as you're using mysqli with prepared statements.
Just quit it and use PDO:
function html_competitive_make_gallery ($init) {
global $USER;
global $link;
$sql_pre = "SELECT form_id, community_id FROM frm_root WHERE user_id = ?
AND page_name = ? ORDER BY last_modified_date DESC LIMIT 1";
$stmt = $link->prepare($sql_pre);
$stmt->execute(array($USER->id, 'competitive'));
return $stmt->fetch();
}

Categories