The same code used as below works fine, but when you un-comment the function and try to call the function, it does not behave the same?
Am trying to standardize the CRUD using functions, but running into issues.
The print_r does not display the output when called inside a function but works when called as is outside of a function
the return value does not return when called via a function
I would like to get the return values via the function and decide what to do next.
Appreciate if you could help me out. Thanks
<?php
//function verifyemail($p_email) {
echo "insde function - " . $p_email;
try {
// $p_email = "r#gmail.com";
include 'db.php';
connectDB('msme_db',1) ;
$sql = "select count(*) as p_exists from msme_users where user_email = '$p_email' ;" ;
echo $sql ;
$result = $__conn->prepare($sql);
$result->execute();
$result->setFetchMode(PDO::FETCH_ASSOC);
$row = $result->fetch() ;
//print_r ($row);
if ($row)
{
$i = $row['p_exists'] ;
return $row !== false ? $row : 'x';
}
} catch (PDOException $e) {
echo " in catch" ;
die("Error occurred:" . $e->getMessage());
}
//} // End of Function
//$email = "r#gmail.com";
//echo sprintf('Email %s is %s', $mail, verifyemail($email)) ;
print_r($row) ;
?>
Problems I see:
1. you have return command in if statement
if ($row)
{
$i = $row['p_exists'] ;
return $row !== false ? $row : 'x';
}
so if is true then you return from function and if is not true then you don't
check this by putting echo inside and see if you see anything
if ($row)
{
echo 'IF Statemen in line: ' . __LINE__ . '<br>' . PHP_EOL;
$i = $row['p_exists'] ;
return $row !== false ? $row : 'x';
}
you should rewrite the code so you always return form the function and use if statement only to assign value to $i or $row
ie like that:
function verifyemail($p_email) {
echo "insde function - " . $p_email;
try {
// $p_email = "r#gmail.com";
include 'db.php';
connectDB('msme_db',1) ;
$sql = "select count(*) as p_exists from msme_users where user_email = '$p_email' ;" ;
echo $sql ;
$result = $__conn->prepare($sql);
$result->execute();
$result->setFetchMode(PDO::FETCH_ASSOC);
$row = $result->fetch() ;
//print_r ($row);
if ($row)
{
$i = $row['p_exists'] ; //<== where do you use $i?
$row !== false ? $row : 'x';
}
} catch (PDOException $e) {
echo " in catch" ;
die("Error occurred:" . $e->getMessage());
}
return $row; //<== here you rentrun from the function
}
// End of Function
// ^ here is place for the comment, not in the line where } is
//$email = "r#gmail.com";
//echo sprintf('Email %s is %s', $mail, verifyemail($email)) ;
print_r($row) ;
?>
If you use return statement without the function body so in the global code scope you end the php script execution
so the code
print_r($row) ;
is never executed
to summarize - put echo statements
echo 'line: ' . __LINE__ . '<br>' . PHP_EOL;
into if statement and other places and check numbers with the code and you'll probably see what you havn't seen where your execution flows where not.
and move return statement outside if statement, perfectly at the end of the function.
Related
I want a function that prepare statement only once. ( Not every time whenever function called for the same Query ).
Because One of Advantage of Prepared Statement is: preparation on the query is done only once (although the statement is executed multiple times)
So whenever I call this Function it will Prepare Statement every time and it's not proper because we will miss taking one of the biggest advantage of Prepared Statement. So that, I put the Condition if( !empty($stmtName) and !isset($GLOBALS[$stmtName]) ) that Check Statement is Already set or not. ( If not then and only then Statement will prepare ) using this we will cover that advantage. But, It generates Binding Parameter failed ERROR.
My Function is here...
function qryInsert( $stmtName, $table, $field, $params, $formats )
{
$query = " INSERT INTO ".$table
." ".( (isset($field) and !empty($field)) ? " ( ".(implode(", ",$field))." ) " : " " ). " "
." VALUES( ". implode(", ", array_map(function($val) { return "?"; }, $field))." ) ";
/*if(!isset($con) or empty($con))
{
$con = $this->connection();
}*/
$a_params = array();
$a_params = array();
$param_type = '';
$n = count($formats);
for($i = 0; $i < $n; $i++)
{
$param_type .= $formats[$i];
}
$a_params[] = & $param_type;
for($i = 0; $i < $n; $i++)
{
$a_params[] = & $params[$i];
}
if( !empty($stmtName) and !isset($GLOBALS[$stmtName]) )
{
$GLOBALS[$stmtName] = $GLOBALS['con']->prepare($query);
// $stmt = $con->prepare($query);
}
if(!($GLOBALS[$stmtName]))
{
echo " Prepare failed: (" . $con->errno . ") " . $con->error; // . " <br> Query : <span style='color:tomato;'> ".$query." </span>"
}
else
{
if(!(call_user_func_array(array($GLOBALS[$stmtName], 'bind_param'), $a_params)))
{
echo "Binding parameters failed: (" . $GLOBALS[$stmtName]->errno . ") " . $GLOBALS[$stmtName]->error;
}
else
{
if(!($GLOBALS[$stmtName]->execute()))
{
echo "Execute failed: (" . $GLOBALS[$stmtName]->errno . ") " . $GLOBALS[$stmtName]->error;
}
else
{
if($meta = $GLOBALS[$stmtName]->result_metadata())
{
while ($field = $meta->fetch_field())
{
$columns[] = &$row[$field->name];
}
if(call_user_func_array(array($GLOBALS[$stmtName], 'bind_result'), $columns))
{
while ($GLOBALS[$stmtName]->fetch())
{
foreach($row as $key => $val)
{
$x[$key] = $val;
}
$results[] = $x;
}
}
else
{
echo " Error occur while Bindig Result...";
}
}
}
}
}
$GLOBALS[$stmtName]->close();
return $results;
}
INPUT:
qryInsert("insStud", "student_master", array("roll_no","name"), array(21,"Mahetab"), array("i","s"));
qryInsert("insStud", "student_master", array("roll_no","name"), array(8,"Sahil"), array("i","s"));
qryInsert("insStud", "student_master", array("roll_no","name"), array(10,"Mahammad"), array("i","s"));
OUTPUT:
First time Record will Insert...
After that raised Binding Parameter failed error...
Without this Condition if( !empty($stmtName) and !isset($GLOBALS[$stmtName]) )
My Code is Work Fine... It havn't any issue... Because It will prepare statement everytime
I used $GLOBALS variable so that whenever function called it uses same GLOBALS variable Otherwise function Perform operation with their private variable which doesn't work properly
Problem Solved...
Just wants to remove $GLOBALS[$stmtName]->close(); statement...
Because It closed statement every time function called...
So, that Binding Parameters failed...
This is cancel_order function,that also in it will call the increase_gameamount() function, i am trying to call increament_gameamount() function it works but when I try to call it from while loop nothing changes in database.
//cancel function
function cancel_order($ord) {
global $conn;
$bqty = 0;
$gqty = 0;
$res = array();
echo "entered cancel function " . $ord . "<br>";
$st = "select (B_qty+G_qty) newqt, B_GM_ID from tb_basket b, tb_game g
where b.B_GM_ID = g.G_ID
and B_O_ID='$ord' ";
$sql = $conn->prepare($st);
$sql->execute();
$sql->bind_result($newqt, $gid);
$i = 0;
while($row = $sql->fetch()) {
$res[$i][0] = $newqt;
$res[$i][1] = $gid;
$i++;
}
$j = 0;
$sql->free_result();
$sql->close();
while($j < sizeof($res)) {
echo $gd = $res[$j][0] . "<br>";
echo $qty = $res[$j][1] . "<br>";
increament_gameamount($gd, $qty);
$j++;
}
}
//increament function
function increament_gameamount($gameid, $new_qty) {
global $conn;
echo "entered increament_gameamount function";
echo $gameid;
echo $new_qty;
$varupdateqty = $conn->prepare("update tb_game set G_qty=? where G_ID=?");
$varupdateqty->bind_param("ss", $new_qty, $gameid);
$varupdateqty->execute();
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
}
As I stated in the comments I think you are failing on the WHERE of your query because
echo $gd=$res[$j][0]."<br>";
is making $gd a string like 125<br> and the DB cannot find that.
Also, this would cause an error but if the type of your column is int and you pass:
echo $qty=$res[$j][1]."<br>";
again you make $qty something like 1000<br> and that would fail again this would be an error the above for ID check would not.
UPDATE
Just realized I did not specifially state the resolution. Set the variables then echo them and you should be all good.
$gd=$res[$j][0];
$qty=$res[$j][1];
echo $gd . "<br>" . $qty . "<br>";
I have a simple function to SELECT from MySQL:
function dbSelect($query) {
$db = db(); // refers to a database connect function
$result = mysqli_query($db, $query);
while ($row = mysqli_fetch_array($result)) {
echo $row['f_name'] . ' : ' . $row['s_name'] . '</br>';
}
}
as you can see it accepts the $query var which would be:
$query = "SELECT * FROM user"; // or whatever
What I would like to do is pass the line:
echo $row['f_name'] . ' : ' . $row['s_name'] . '</br>';
as an arg in the function call, eg:
function dbSelect($query, $display)
and the $display be something like (which I would echo out under the while statement):
$display = $row['f_name'] . " : " . $row['s_name'] . "</br>";
The above line will give an undefined variable error, I know why.
How would I go about passing the $display to the function or defining it correctly?
ps. I know there is not any error checking, I'm just trying to figure this out, will add that later. :-)
Thanks for any help
Try this, to maintain separation from program logic to program output:
// some configuration file you include
$db = db(); // refers to a database connect function
// some common functions file
function dbSelect($query)
{
global $db;
$result = mysqli_query($db, $query);
return $result;
}
// output script
$records = dbSelect('SELECT * FROM somewhere');
// loop until cannot fetch any more rows from the record set
while ($row = mysqli_fetch_array($records))
{
echo $row['f_name'] . ' : ' . $row['s_name'] . '</br>';
}
Personally I would pass a template name into the function and have the template stored somewhere as a snippet of html which has standard replacement vars
So you may have something like this (note this won't work out the box will need some fiddling but its the concept)
define TEMPLATE_NAME = "<tr><td>%COL1%</td><td>%COL2</td></tr>";
$colstospitout = array('COL1'=>'f_name','COL2'=>'s_name');
function dbSelect($query,$reportcols,$templatename) {
while ($row = mysqli_fetch_array($result))
{
$template = str_replace("%COL1%",$reportcols['COL1'],$templatename);
$template = str_replace("%COL2%",$reportcols['COL2'],$templatename);
echo $template;
}
}
dbSelect($inputquery,$colstospitout,TEMPLATE_NAME);
There are two ways to do it. The proper way to do it would be to have this function only run the query and return the results. You could make another function that outputs the results. This way you have a clear separation of logic in your code.
However, if you know that you want it done in this way, something like this should work:
function dbSelect($query, $format) {
$db = db();
$result = mysqli_query($db, $query);
while ($row = mysqli_fetch_array($result))
{
echo preg_replace_callback("/\{\{\s*(\w+)\s*\}\}/", function($matches) use ($row) { $column = trim($matches[1]); return isset($row[$column]) ? $row[$column] : $matches[0]; }, $format);
}
}
Where the arguments could look something like:
dbSelect("SELECT * FROM user", "{{ f_name }} {{ s_name }}");
You can't pass it the way that you're passing it because $row doesn't exist when you call the function (because it gets defined inside of the function). In addition, your variables in would be evaluated once when the function is called, not each time in the while loop.
And before anyone makes a "suggestion": eval is not an option.
I am trying to execute some lines of php code, but it seems that tey are not being execute in the required order. Here is a code snippet:-
if( !empty($_POST['val']) )
{
$val = Get_Val($sid, $_POST['val'], $lnk);
if($val)
{
echo "<br />Here Value : " . $val;
}
else
{
echo "Invalid Value.";
}
}
When I echo the value before returning in function Get_Val() it shows a positive number for some set of valid arguments, which means that the If-condition is true, but when I execute the code the Else part is being executed. Though the output appear in order, they are not consistent. I hope I have made the problem clear.
Any amount of help is appreciated. Thanks!
Here is Get_Val() function:-
function Get_Val( $sid, $a, $link)
{
//check is name is already present in table
$query = "SELECT val FROM store WHERE name = \"" . $a . "\""; //val is auto incremented in sql
$result = mysql_query( $query ,$link ) or die( mysql_error());
if($result)
{
$count = mysql_num_rows($result);
if( $count == 0 ) //insert name and the return val
{
$query_x = "INSERT INTO store(name) VALUES('" . $a . "')";
$result = mysql_query( $query_x ,$link ) or die( mysql_error());
if($result)//If new name inserted then return the 'val'
{
Get_Val($sid, $a,$link);
}
}
else
{
$row = mysql_fetch_assoc( $result );
echo "Val in Get_Val : " . $row['val'];
return $row['val'];
}
}
else
{
echo "Unexpected Error Occured...!!!";
exit(0);
}
}
what's with this:
if( $count Val in Get_Val : " . $row['val'];
return $row['val'];
}
are you sure that $_POST['val'] is a valid value that is stored in the db?
Get_Val does not return a value if $count == 0. Add a return statement before the recursive call. Like this:
...
if( $count == 0 ) //insert name and the return val
{
$query_x = "INSERT INTO store(name) VALUES('" . $a . "')";
$result = mysql_query( $query_x ,$link ) or die( mysql_error());
if($result)//If new name inserted then return the 'val'
{
return Get_Val($sid, $a,$link);
}
}
...
I'm using a prepared statement for a query that returns multiple results, which I'd want to have in an array. But bind_result won't work with arrays, so this is how I do it:
$read_items = $db->stmt_init();
$read_items->prepare("SELECT item_id, item_name FROM items");
$read_items->execute();
$read_items->bind_result($var1, $var2);
while ($read_items->fetch()) {
$item_id[] = $var1;
$item_name[] = $var2;
}
Is there clearer/better/more elegant way to put results into $item_id and $item_name arrays?
As it's visible from above, I'm using $var1 and $var2 like "intermediates" - and constantly have feeling there must be a better way.
Thanks.
I can't take credit for it, but the PHP manual has a nice solution (pasted verbatim):
<?php
// blah blah...
call_user_func_array(array($mysqli_stmt_object, "bind_result"), $byref_array_for_fields);
// returns a copy of a value
$copy = create_function('$a', 'return $a;');
$results = array();
while ($mysqli_stmt_object->fetch()) {
// array_map will preserve keys when done here and this way
$results[] = array_map($copy, $byref_array_for_fields);
}
You can use the Argument unpacking(...) operator.
$results = array(null, null);
$read_items->bind_result(...$results);
while ($read_items->fetch()) {
$item_id[] = $result[0];
$item_name[] = $result[1];
}
I really don't see the point of putting your item id's and item names in different arrays, you're breaking up a single object in two collections for ??? no reason . yes.
So, going back to this, what you should be doing is :
$items[$i]['var1']=$var1;
$items[$i]['var2']=$var2;
But this of course is still not very good.
The correct solution is to have a function that maps your mysqli result to an array so you can directly start working on that, whatever the query, here's mine - works in a few db's but not all are up to date at the moment :
function connectmysqldb($database,$host,$port,$user,$password){
global $conn;
$conn=mysqli_connect($host, $user, $password, $database,$port);
if (!$conn){
die('Error: Could not connect: ' . mysqli_connect_error());
}
return $conn;
}
function connectpgdb($database,$host,$port,$user,$password){
$connectString = 'host=' . $host . ' port=' . $port . ' dbname=' . $database . ' user=' . $user . ' password=' . $password;
$conn = pg_connect ($connectString);
if (!$conn)
{
die('Error: Could not connect: ' . pg_last_error());
}
return $conn;
}
function connectmssqldb($dbname,$host,$port,$uid,$pw){
$connectionOptions = array("UID"=>$uid,"PWD"=>$pw);
$conn = sqlsrv_connect( $host, $connectionOptions);
if (!$conn)
{
die('Error: Could not connect: ' . print_r( sqlsrv_errors(), true));
}
return $conn;
}
function sqlec($query,$dbtype,$dbname,$host,$port,$uid,$pw){
switch($dbtype){
default:
$res="Database Type not Recognized : $dbtype";
break;
case "mysql":
global $conn;
if(!isset($conn)){
$conn=connectmysqldb($dbname,$host,$port,$uid,$pw);
}
$clone=mysqli_multi_query($conn,$query);
if(!$clone){
die('Error: ' . mysqli_error($conn));
}else{
$clonearray=array();
$i=0;
if ($clone = mysqli_store_result($conn)) {
while ($row = mysqli_fetch_assoc($clone)){
$clonearray[$i]=$row;
$i++;
}
mysqli_free_result($clone);
}
$res=$clonearray;
}
break;
case "postgres":
$conn=connectpgdb($dbname,$host,$port,$uid,$pw);
$clone=pg_query($conn,$query);
if (!$clone)
{
die('Error: ' . pg_last_error());
}else{
$clonearray=array();
$i=0;
while ($row = pg_fetch_row($clone))
{
$count = count($row);
$y = 0;
while ($y < $count)
{
$c_row = current($row);
$clonearray[$i][pg_field_name($clone,$y)] = $c_row;
next($row);
$y = $y + 1;
}
$i = $i + 1;
}
pg_free_result($clone);
pg_close($conn);
$res=$clonearray;
}
break;
case "mssql":
$conn=connectmssqldb($dbname,$host,$port,$uid,$pw);
$res=sqlsrv_query($conn,$query);
if (!$res)
{
die( "Error in statement execution.\n".print_r( sqlsrv_errors(), true));
}else{
$i=0;
$sqlsarray=array();
while( $row = sqlsrv_fetch_array( $res, SQLSRV_FETCH_ASSOC))
{
if($i==0){
$arrk=array_keys($row);
}
$j=0;
while($j<count($arrk)){
$sqlsarray[$i][$arrk[$j]]=$row[$arrk[$j]];
$j++;
}
$i++;
}
$res=$sqlsarray;
}
break;
}
return $res;
}
function local_sqlec($query){
global $db_server;
global $db_db;
global $db_port;
global $db_username;
global $db_password;
return sqlec($query,"mysql",$db_db,$db_server,$db_port,$db_username,$db_password);
}
Which I use like this :
$r=local_sqlec("SELECT test1,test2 FROM test");
$i=0;
echo "last id =".($r[0]['test1'])."<br>";
echo "Row count =".($r[0]['test2'])."<br>";
while($i<$r[0]['test2']){
echo "inserted id =".($r[0]['test1']+$i)."<br>";
$i++;
}