[language : php]
i have a function that have three mysql prepare statements..
when call the function from Api while the function is already processing .. i want to wait that call and resume after the processing finish ...
actually my problem is ... in my function
my first mysql prepare statement select a value from database and bind that result..
the second prepare statement use that result ..
but another call select value from database without wait for the second prepare statement execute from first call...
//function sample...
public function saveSales($query1,$query2,$query3){
//query1 execute and return a result from database
//using that result execute query 2
//execute query 3
// i want to run this three querys without interrupt from another call
}
My Actual Code :
[index.php : slimframework(Api)]
$app->post('/savesalesnew', function(Request $request, Response $response){
$request_data = $request->getParsedBody();
$sm= $request_data['sm'];
$st= $request_data['st'];
$trans = $request_data['trans'];
$user= $request_data['user'];
$pass = $request_data['pass'];
$maxfind = $request_data['maxfind'];
$db = new DbOperations;
$queryPostResult = $db->saveSales($sm,$st,$trans,$user,$pass,$maxfind);
$response_data=$queryPostResult;
$response->write(json_encode($response_data));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
});
[Db operations.php]
public function saveSales($sm,$st,$trans,$user,$pass,$maxfind){
$stmt = $this->con->prepare("SELECT emp_pass FROM emp WHERE emp_name ='$user'");
$stmt->execute();
$stmt->bind_result($password);
$stmt->fetch();
if(strcmp($pass, $password) !== 0) {
return false;
}
$stmt->close();
$mysqli = new mysqli(//connection parameters);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$mysqli->autocommit(FALSE);
$stmt1 = $this->con->prepare("$maxfind");
$stmt1->execute();
$stmt1->bind_result($maxInvoice);
$stmt1->fetch();
$stmt1->close();
$sm = str_replace("#%#####23###3", $maxInvoice, $sm);
$st = str_replace("#%#####23###3", $maxInvoice, $st);
$trans = str_replace("#%#####23###3", $maxInvoice, $trans);
$mysqli->query("$sm");
$mysqli->query("$st");
$mysqli->query("$trans");
$mysqli->commit();
$mysqli->close();
return true;
}
//-----------------------------
if you have long process on server, you need a column flag in database if data ready or not. set "0" if data not ready "1" in progress "2" ready.
Related
I am working to create a content class which will pull all content from the database via a PDO, then run the results through a method which will convert the results into objects, and the loop through the objects, and echo the object to a specific module of the webpage.
What is expected
When the class is activated, there will be an instance created via a PDO that will retrieve the needed data from the mysql database. Then this information will echo out and display on the webpage.
What is happening
I end up with no errors and the boolean number "1" where content should be. At first I thought this was an sql error. I get the same result "1" if I use print_r($query_result). See my tests below.
My class code is below
<?php
class Content {
// --- START OF ACTIVE RECORD CODE ---
public $n_id;
public $n_name;
public $n_text;
public $n_photo;
// Instantiating a STATIC Database Connection for the class to use
static protected $dbconnect;
static public function database($dbconnect) {
self::$dbconnect = $dbconnect;
}
// constructing arguments
public function __construct($args=[]) {
$this->n_id = $args['n_id'] ?? '';
$this->n_name = $args['n_name'] ?? '';
$this->n_text = $args['n_text'] ?? '';
$this->n_photo = $args['n_photo'] ?? '';
}
// Multi use method to pass in sql that will execute the PDO only two parameters are bound ID and contentText.
static public function find_by_sql($sql) {
// -------------BEGIN PDO-----------
// preparing PDO by loading sql, calling db connection, and storing in variable $stmt
$stmt = self::$dbconnect->prepare($sql);
// Binding Parameters for sql
$stmt->bindParam(':nid', $n_id, PDO::PARAM_INT);
$stmt->bindParam(':nall', $n_name, PDO::PARAM_STR);
$stmt->bindParam(':ntext', $n_text, PDO::PARAM_STR);
$stmt->bindParam(':nphoto', $n_photo, PDO::PARAM_INT);
// executing $stmt PDO and storing the result in $stmt
$query_result = $stmt->execute();
return $query_result;
// clearing the PDO after information is stored in $record
$stmt->closeCursor();
// ------------END PDO ----------
// Checking to see if a result exist. If nop result is stored in $stmt, then it will echo "Database query failed."
if(!$query_result) {
exit("Query doesn't exist.");
}
// -------- BEGIN TURNING RESULTS INTO OBJECTS --------
$object_array = [];
// The result $stmt will be stored in the variable $record
while($record = $query_result->fetchAll()) {
// Taking $record and passing it to the static method instantiate() - see below. This method will return the $object_array.
$object_array[] = self::instantiate($record);
}
return $object_array;
// ------------ END TURNING RESULTS INTO OBJECTS --------
}
// method to test passing $sql to method find_all_sql();
static public function find_all(){
$sql = "SELECT * FROM nmain WHERE nid = :id AND nall = :nall AND ntext = :ntext AND nphoto = :nphoto";
return self::find_by_sql($sql);
}
// --- BEGIN INSTANTIATE METHOD TO CREATE OBJECTS ---
static protected function instantiate($record) {
$object = new self;
// Auto assign values
foreach($record as $property => $value) {
if(property_exists($object, $property)){
$object->$property = $value;
}
}
return $object;
}
// ----- END INSTANTIATE OF RECORD TO CREATE OBJECTS ---
// ---END OF ACTIVE RECORD CODE---
}
?>
**On my html webpage:**
$contents = Content::find_all();
foreach ((array) $contents as $content) {
echo $content;
}
What I have tested
This is the output I get when I run var_dump($stmt);
object(PDOStatement)#3 (1) { ["queryString"]=> string(119) "SELECT * FROM ndb WHERE id = :id AND nall = :nall AND ntext = :ntext AND nphoto = :nphoto" }
If I copy the query and paste it in myphpadmin the query will run binding the params.
This is the output if I run var_dump($query_result):
bool(true) if I use print_r($query_result) I get "1"
This passes my if(!$query_result) test
If I run var_dump($record) or var_dump($query_result) I get nothing. It seems as if $query_result, because it is a bool, has no array to pass to $record.Therefore, there is nothing to convert to an object.I am at a loss here. Is it my PDO binding?
Your fetch should be on the statement and not the result of the execute (which is just to say the execute has succeeded or failed), also fetchAll will attempt to return all records, what you most likely want is fetch to process 1 record at a time. So you should have something like...
while($record = $stmt->fetch()) {
You can now remove the earlier return which is stopping further processing.
I am trying to build database class using PDO this my first time using pdo so while i am building i am stuck in this problem i was able create and connect to database using class but problem is when i am trying to execute and fetch returned data error says
Call to a member function fetch() on boolean
and yet i can do this fetching inside the class this problem arise only when i am trying to fetch returned data and i have echoed the returned data it is returning 1
This is function that's trying to return (did not use parameters just using dummy)
public function init($query,$param =[]){
if(!$this->bConnected) { $this->Connect(); }
try{
$stmt = $this->pdo->prepare('SELECT * FROM business');
$stmt->execute();
return $stmt->execute();
}catch(Exception $e){
echo $e->getMessage();
}
}
Calling to class object name is $myobj
$stmt = $myobj->init('SELECT * FROM business',$value);
while($rows = $stmt->fetch(PDO::FETCH_ASSOC)){
echo( $rows['bs_name'] ." |" .$rows['bs_id']. "<br>");
}
This is same code only difference is this is inside the class.working without any errors
public function init($query,$param =[]){
if(!$this->bConnected) { $this->Connect(); }
try{
$stmt = $this->pdo->prepare('SELECT * FROM business');
$stmt->execute();
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
while($rows = $stmt->fetch(PDO::FETCH_ASSOC)){
echo( $rows['bs_name'] ." |" .$rows['bs_id']. "<br>");
}
}catch(Exception $e){
echo $e->getMessage();
}
}
Your method returns the result of $stmt->execute() (a boolean indicating success/failure of the statement execution, not the query results).
$stmt = $this->pdo->prepare('SELECT * FROM business');
return $stmt->execute();
Instead, for the method to work the way you're using it, you need to execute the statement and then return the statement itself, not the result of execute().
$stmt = $this->pdo->prepare('SELECT * FROM business');
$stmt->execute();
return $stmt;
An example of one of my queries...
public function db_query_select($query, $params, $param_types){
$dbc = $this->dbConnect();
if($stmt = $dbc->prepare($query)){
//prepared.
//move the types to the front of the param array
array_unshift($params, $param_types);
//call the bind param function with the parameters passed in by reference
//bind_param only allows by reference.
call_user_func_array(array($stmt, "bind_param"), $this->paramsToRefs($params));
//binded.
//attempt to execute the sql statement.
if ($stmt->execute()){
$result = $stmt->get_result();
$stmt->close();
$dbc->close();
return $result;
}
}
//must have failed...
return NULL;
}
how can I change stmt get_result(); to something that is accepted by shared servers/hosts without the native driver... mysqlnd.
Anyone know? without changing all of my functions that use this database function.
Thanks.
UPDATED:::: Thanks to #your common sense, See Answer.
I believe this is what I was after. Hope it helps anyone that was having the same problem as myself. PDO vs MySQLi, seems simpler... no user call func or anything like that.
DB HANDLER:
private function dbConnect(){
$config = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/NTConfig.ini');
try {
$dbc = new PDO('mysql:host='.$config['DB_HOST'].';dbname='.$config['DB_DATABASE'].'', $config['DB_USER'], $config['DB_PASSWORD']);
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
return $dbc;
}
public function db_query_select($query, $params){
$dbc = $this->dbConnect();
if($stmt = $dbc->prepare($query)){
//prepared.
//attempt to execute the sql statement.
if ($stmt->execute($params)){
$result = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($result);
//$stmt->close();
//$dbc->close();
return $result;
}
}
//must have failed...
return NULL;
}
Outside the DBHANDLER
$query = "SELECT error_desc FROM nt_errors WHERE error_code = :ERROR_CODE LIMIT 1";
//array: holds parameters for the query.
$params = array(
':ERROR_CODE' => $code
);
$result = $db->db_query_select($query, $params);
if ($result == NULL){
$errorText = 'ERROR: Failed to retrieve error';
}
else{
//var_dump($result);
$errorText = $result['error_desc'];
PDO is not only much more user friendly than mysqli but also doesn't have any of such a nasty drawbacks. So I strongly suggest to use PDO instead of mysqli.
With DO, the function you're after should be as simple as this
function run($sql, $args = NULL)
{
$pdo = ...;//your means of getting the connection variable
$stmt = $pdo->prepare($sql);
$stmt->execute($args);
return $stmt;
}
After gettin the function's result, you can chain a fetch method to its call, fetchColumn() in your case.
Given your code is mostly procedural, let me suggest you a very simple PDO wrapper I wrote. So the full code would be:
$sql = "SELECT error_desc FROM nt_errors WHERE error_code = ?";
$errorText = DB::run($sql,[$code])->fetchColumn();
if (!$errorText){
$errorText = 'ERROR: Failed to retrieve error';
}
Here DB class is a better replacement of your dbConnect() function, and run() method is a replacement for db_query_select() that actually can be used for any query type, including insert, update or anything.
I have a another php file that has the function to connect to the database (does so successfully) and also a function getEvent that contains the sql statement.
The code below successfully retrieves one data row from the database but i need it to return all data from the table.
<?php
// include db connect class
require_once 'include/DB_Functions.php';
// connecting to db
$db = new DB_Functions();
// array for JSON response
$response = array();
// get all events from events table
$event = $db->getEvent();
// check for empty result
if($event !=FALSE){
$response["error"]=FALSE;
$response["uuid"] = $event["eventID"];
$response["eventdetails"]["title"] = $event["title"];
echo json_encode($response);
}else{
$response["error"]=TRUE;
$response["error_msg"] = "No events to display";
echo json_encode($response);
}
?>
the getEvent method
public function getEvent(){
$stmt= $this->conn->prepare("SELECT * from eventdetails");
$stmt->execute();
$event= $stmt->store_result();
if ($stmt->execute()) {
$event = $stmt->get_result()->fetch_assoc();
$stmt->close();
return $event;
} else {
// events dont existed
$stmt->close();
return null;
}
If youwant to return an array containing all the results from a query then use the fetchAll() method of the PDOStatement Class
public function getEvent(){
$stmt = $this->conn->prepare("SELECT * from eventdetails");
$stmt->execute();
$events = $stmt->fetchAll();
return $events;
}
I have done this before but am quite new to mysqli and prepared statements (as I'm sure you can see from this issue).
Where am I going wrong?
here is my connection function (part of the 'Connect' class)
public function site_db()
{
// Connect to MySQL
$link = mysqli_connect(SITE_HOST, SITE_ID, SITE_PW, SITE_DB);
// Check for Errors
if(mysqli_connect_errno())
{
//echo mysqli_connect_error(); //shouldnt show client specific error information.
die('Error connecting to mysql database please report.');
}
}
Heres the function which is causing the error:
public function exists ($what, $who)
{
$query = "SELECT * FROM users WHERE ? = ?";
// Get instance of statement
$stmt = $mysqli->stmt_init();
// Prepare query
if($stmt->prepare($query))
{
// Bind Parameters
$stmt->bind_param("ss", $what, $who);
// Execute statement
$stmt->execute();
// Bind result variables
$stmt->bind_result($result);
// Fetch Value
$stmt->fetch();
// catch num_rows result as variable
$username_result = $result->num_rows;
// Close Statement
$stmt->close();
}
if ($username_result != 0)
{
return true;
echo 'true';
}
else
{
return false;
echo 'false';
}
}
the error I get:
PHP Fatal error: Call to a member function stmt_init() on a non-object in somefile.php on line X
It is referring to the line:
$stmt = $mysqli->stmt_init();
am I making a stupid error here? Howcome I can't call that?
EDIT//
NOTE: I didn't make this very clear, but these two functions are within different classes.
public function site_db()
{
// Connect to MySQL
$mysqli = mysqli_connect(SITE_HOST, SITE_ID, SITE_PW, SITE_DB);
// Check for Errors
if(mysqli_connect_errno())
{
//echo mysqli_connect_error(); //shouldnt show client specific error information.
die('Error connecting to mysql database please report.');
}
return $mysqli;
}
public function exists (Mysqli $mysqli, $what, $who)
{
$query = "SELECT * FROM users WHERE ? = ?";
// Get instance of statement
$stmt = $mysqli->stmt_init();
// Prepare query
if($stmt->prepare($query))
{
// Bind Parameters
$stmt->bind_param("ss", $what, $who);
// Execute statement
$stmt->execute();
// Bind result variables
$stmt->bind_result($result);
// Fetch Value
$stmt->fetch();
// catch num_rows result as variable
$username_result = $result->num_rows;
// Close Statement
$stmt->close();
}
if ($username_result != 0)
{
return true;
echo 'true';
}
else
{
return false;
echo 'false';
}
}
How to use:
Instantiate first class that have site_db() method
$db = new Class();
Then instantiate second class that have exist() method
$query = new Class();
Then simply
$query->exist($db->site_db(), $what, $who );
it's because your $mysqli is not declared inside function exists(). Try a global $mysqli inside function exists() if your $mysqli is declared outside the function.
Or, probably better - make $mysql an new object inside your Connect class:
$this->mysqli = mysqli_connect(SITE_HOST, SITE_ID, SITE_PW, SITE_DB);
and in your function exists()
$stmt = $this->mysqli->stmt_init();