Saprfc table read with filter - php

I'm new in php saprfc. I use an our integrated function, but now I need to read lines from a table. But how can I do to read only a few lines, filter the results by a criteria, because this table has some millions of rows.
Is it possible?

Here is a code part, that is use recently, works well and quick on very big tables too. I hope it helps others too.
//Try to connect to SAP using our Login array
$rfc = saprfc_open ($saplogin);
IF (! $rfc ) { ECHO "The RFC connection has failed with the following error:".saprfc_error();EXIT; }
//We must know if the function really exists
$fce = saprfc_function_discover($rfc, "RFC_READ_TABLE");
IF (! $fce ) { ECHO "The function module has failed.";ECHO $rfc;EXIT; }
//Convert to uppercase the name of the table to show
$Table = "HERE_THE_TABLE_NAME";
//Pass import parameters
saprfc_import ($fce,"QUERY_TABLE",$Table);saprfc_import ($fce,"DELIMITER","/");
//Pass table parameters
saprfc_table_init ($fce,"OPTIONS");
saprfc_table_append ($fce,"OPTIONS", array ("TEXT"=>"TABLE_FIELD_NAME = '{$input}'")); //input field, filter by this variable
saprfc_table_init ($fce,"FIELDS");
saprfc_table_append ($fce,"FIELDS", array ("FIELDNAME"=>"INT_UI")); //wanted answer field
saprfc_table_init ($fce,"DATA");
//Call and execute the function
$rc = saprfc_call_and_receive ($fce);
if ($rc != SAPRFC_OK)
{
if ($rfc == SAPRFC_EXCEPTION ) { echo ("Exception raised: ".saprfc_exception($fce)); }
else { echo ("Call error: ".saprfc_error($fce)); }
exit;
}
//Fetch the data from the internal tables
$data_row = saprfc_table_rows ($fce,"DATA");$field_row = saprfc_table_rows ($fce,"FIELDS");
for($i=1; $i<=$data_row ; $i++)
{ $DATA[$i] = saprfc_table_read ($fce,"DATA",$i);$TEST[] = SPLIT("/",$DATA[$i]['WA']); } // get the rows to $TEST variable
//release the function and close the connection
saprfc_function_free($fce);

Related

Programing with php7.0 a function to call mysql stored procedures dynamically

Just a few words to explain what I want to do.
I want to extend my lib with a function able to call stored procedures. I found here the steps to make it but I have a hard time to make it generic.
To achieve this, I've read that I have to use the call_user_func_array on mysqli_stmt_bind_param because I know only at execution the number of parameters IN, there types and the number of OUT
Here a few details of what I've done:
create a connection to the DB
set the charset
build the call string for example CALL (?,?,?,#outParam1,#outParam2)
prepare the call string
build an array of parameters to use with call_user_func_array that will call mysqli_stmt_bind_param <= this what give's me troubles
call mysql_stmt_excute
finally, make a select to get out parameters.
Here the main parts of code :
function executeProc($sProcName, $sInParamTypes, $aInParam, $iNumberParameterOut=0)
{
$oConnection = #mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DBNAME);
mysqli_set_charset($oConnection, "utf8");
/* code to build the $sCallStr */
$oMysqlCall = mysqli_prepare($oConnection, $sCallStr);
array_unshift($aFunctionParam, $oMysqlCall, $sInParamTypes);
$aFunctionParam = array_merge($aFunctionParam, $aInParam);
call_user_func_array("mysqli_stmt_bind_param", $aFunctionParam);
mysqli_stmt_execute($oMysqlCall);
}
the return of call_user_func_array is NULL. I've tryed to call the function manualy :
mysqli_stmt_bind_param($aFunctionParam[0], $aFunctionParam[1], $aFunctionParam[2], $aFunctionParam[3], $aFunctionParam[4], $aFunctionParam[5], $aFunctionParam[6], $aFunctionParam[7]);
And it works. I see the result in the DB and the return of the function is TRUE.
Can someone help here? Is there another way to pass the array of parameters? (like by reference ?)
Thx a lot for your help
You could use "Argument unpacking" using ... :
mysqli_stmt_bind_param($oMysqlCall, $sInParamTypes, ...$aInParam);
This will work with variables passed by references, and there is no need to use array_unshift() and array_merge() to build your parameters.
Example :
function foo(&$a, &$b, &$c) { var_dump($a,$b,$c); }
This will works :
$arr = [1,2,3];
foo(...$arr); // Works
But this will generate a warning :
$arr = [1,2,3];
call_user_func_array('foo', $arr);
// Warning: Parameter 1 to foo() expected to be a reference, value given
Here is a feedback to my problem:
I've managed with your help and this post https://stackoverflow.com/a/48128540/6050817 to make my funtion and it works great.
I wanted to post the complet code I've made to share. This function execute a stored procedure and collectes all the datas selected by this procedure and all the out parameters
function executeProc($sProcName, $sInParamTypes = "", $aInParam = null, $iNumberParameterOut=0)
{
global $oError;
$oError = false;
$aRows = array();
$sCallStr = "";
$sSelectOutParam = "";
$aReturn = array();
if($aInParam == null)
{
$aInParam = array();
}
$iLevel = error_reporting(9);
// open connection to DB
$oConnection = #mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DBNAME);
if ($oConnection === false)
{
$oError = mysqli_error($oConnection);
return false;
}
// we set the character set
mysqli_set_charset($oConnection, "utf8");
// we build the call to the stored procedure
$sCallStr = "CALL ";
$sCallStr = $sCallStr.$sProcName."(";
// we add the IN parameters
foreach($aInParam AS $sParam)
{
$sCallStr = $sCallStr."?,";
}
// we add the OUT parameters (since we can't access directly the out parameters, we store their value in variables # on the DB) we will access theme at the end
for($iIndex=0; $iIndex<$iNumberParameterOut; $iIndex++)
{
$sSelectOutParam = $sSelectOutParam."#outParam".$iIndex.",";
}
// we remove the unwanted coma
if($iNumberParameterOut > 0)
{
$sSelectOutParam = rtrim($sSelectOutParam, ",");
}
else
{
$sCallStr = rtrim($sCallStr, ",");
}
// we merge the two parameters string and add the final parenthesis
$sCallStr = $sCallStr.$sSelectOutParam.")";
// we prepare the call
$oMysqlCall = mysqli_prepare($oConnection, $sCallStr);
// only if we have parameters we bind the call with the types and the list of IN parameters. If no parameters is waited by the stored procedure we don't need to bind
if(count($aInParam) > 0)
{
mysqli_stmt_bind_param($oMysqlCall, $sInParamTypes, ...$aInParam);
}
// we execute the stored procedure
mysqli_stmt_execute($oMysqlCall);
// we get the data that would be returned by select in the procedure
while ($oResult = mysqli_stmt_get_result($oMysqlCall))
{
if (mysqli_num_rows($oResult) > 0)
{
while ($oRow = mysqli_fetch_assoc($oResult))
{
foreach($oRow as $key => $val)
{
$aRows[$key] = $val;
}
$aReturn[] = $aRows;
$aRows = array();
}
}
// we free the return variable
mysqli_free_result($oResult);
// we get the next return
mysqli_stmt_next_result($oMysqlCall);
}
// we have to close the call to get the out parameters
mysqli_stmt_close($oMysqlCall);
if($iNumberParameterOut > 0)
{
// to get the out parameters stored in variables we have to make a select on on the DB
$oResult = mysqli_query($oConnection, "SELECT ".$sSelectOutParam.";");
// for every variable we create a row and add to an array
for($iIndex=0; $iIndex<$iNumberParameterOut; $iIndex++)
{
$iReturnIndex = 0;
while($oRow = mysqli_fetch_assoc($oResult))
{
if ($oRow===false) $oRow = array();
$aRows[key($oRow)] = $oRow[key($oRow)];
$iReturnIndex++;
}
if ($oRow===false && $iReturnIndex==0)
{
$aRows[0] = array();
}
}
// stored in the out key of our main return variable
$aReturn["out"] = $aRows;
}
// we free the rest
mysqli_free_result($oResult);
mysqli_close($oConnection);
error_reporting($iLevel);
// and return the data
return $aReturn;
}
}
Hope this help someone. Feel free to comment or ask if you don't understand something

Join multiple strings from php & sql foreach loop and return as 1 string

I'm trying to build a permission/action control system for my users.
There are 3 tables:
appName_actions:
appName_roles:
appName_roles_members:
There are 2 functions that will obtain the relevant data:
$memRoleIDs = AccessControl::get_memberRoleIDs($appName);
$memActionIDs = AccessControl::get_memberActionIDs($appName, $memRoleIDs);
get_memberRoleIDs works fine, it targets member 327 and returns the desired '2,4'
That is then passed to get_memberActionIDs as '2,4'
It's at this point I'm having trouble working out how to return all the actionIDs in one variable/string.
get_memberActionIDs:
public static function get_memberActionIDs($appName = NULL, $memRoleIDs = NULL)
{
if($appName !== NULL && $memRoleIDs !== NULL)
{
$tbl = 'app_'.$appName.'_roles';
$memRoleID = explode(',',$memRoleIDs);
foreach($memRoleID as $value)
{
$db = openDB();
$sql = $db->prepare("SELECT actionIDs FROM $tbl WHERE roleID = '$value'");
if(!$sql->execute())
{
logThis('ERROR_crit' , 'Database Query Failed !!!' , 1 , __FILE__ , __LINE__);
die('<h2>There was a critical error and data has not been loaded correctly. Developers have been notified.</h2><h3>Please try reloading the page</h3>');
}
else
{
// sql executed ok - bind fetch results
$sql->bind_result($actionID);
$sql->fetch();
print $actionID.'<br>';
}
}// return all the actionIDs as 1 variable here
}
}// end func
Now with this, there is success up-to-a-point. It prints out the correct info:
1,2,3,4
5
And this is where I cannot go any further :(
I've looked into GROUP_CONCAT and CONCAT in the SELECT statement and .= in the PHP loop, but I just cannot figure this out.
I'd like to return this as '1,2,3,4,5' all in 1 string.
If you could point me in the right direction I would be very grateful :)
Instead of printing out separate results, create a single string and print after the loop exits. You say you've tried this but you didn't include the relevant code to check if the implementation is correct. Is this what you did?
public static function get_memberActionIDs($appName = NULL, $memRoleIDs = NULL)
{
if($appName !== NULL && $memRoleIDs !== NULL)
{
$tbl = 'app_'.$appName.'_roles';
$memRoleID = explode(',',$memRoleIDs);
$result = "";
foreach($memRoleID as $value)
{
$db = openDB();
$sql = $db->prepare("SELECT actionIDs FROM $tbl WHERE roleID = '$value'");
if(!$sql->execute())
{
logThis('ERROR_crit' , 'Database Query Failed !!!' , 1 , __FILE__ , __LINE__);
die('<h2>There was a critical error and data has not been loaded correctly. Developers have been notified.</h2><h3>Please try reloading the page</h3>');
}
else
{
// sql executed ok - bind fetch results
$sql->bind_result($actionID);
$sql->fetch();
$result .= $actionID;
}
}// return all the actionIDs as 1 variable here
print $result.'<br>';
}
}// end func

php error insert data with value including addition sign (+) to database

There is an error while i insert "3 + 1 room" or update description area with "3 + 1 room" in MySQL database.
I saw there is no addition sign "+" in MySQL log (data inserted in database)
UPDATE testtable set status='0',title='3 1 room',
description='3 1 Daire. 1 Balkon kapalı.' WHERE id='60';
create table testtable ( id int(11), status tinyint(4), title varchar(20),
description text) ENGINE=InnoDB DEFAULT CHARSET=utf8
php file
$baglanti=new PDO("mysql:host="localhost";dbname="test";charset=utf8",$us
ername,$passwd) or die("error");
$val=$baglanti->exec("UPDATE testtable set status='0',title='$title',
description='$dest' WHERE ad_no='$ad_no' ");
return $val;
What should I do?
EDIT
update.php
<?php
include("database.php");
$fields = array();
$values=array();
$fvalue=$_POST['id'];
$table=$_POST['table'];
foreach ($_POST as $key => $value) {
if( $key!='table' && $key!='id' && $key!='alan'){
if( strpos($key,"date")){
$datet=new DateTime($value);
$value=$datet->format('Y-m-d');
}
array_push($fields,$key);
array_push($values,$value);
}
}
$alan=$_POST['alan'];
$ID=Updt($table,$fields,$values,$alan,$fvalue);
if($ID!=0){
echo $ID;
}
?>
database.php
<?php
$baglanti=new PDO("mysql:host="localhost";dbname="test";charset=utf8",$us
ername,$passwd) or die("error");
#UPDATE
function Updt($table,$set,$value,$field,$fvalue){
$bag=$GLOBALS['baglanti'];
$sts='';
if(is_array($set)){
for ($i=0; $i < count($set); $i++) {
$sts.=$set[$i]."='".$value[$i]."',";
}
$sts=rtrim($sts,",");
}else{
$sts=$set."='".$value."'";
}
$val=$bag->exec("UPDATE $table set $sts WHERE $field='$fvalue'");
return $val;
}
?>
this one, programmers wrote code. I try to take question parts from all code. There were lots of codes in file.
My guess is that you are not generating the query you think you are.
This should allow you to see the query.
I have also added some error checking, that really should be used in this code.
I have amended the connection line as I am sure a newline in the middle of the $username variable will cause an error.
database.php
<?php
try {
$baglanti = new PDO("mysql:host=localhost;dbname=test;charset=utf8",
$username,$passwd);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
#UPDATE
function Updt($table,$set,$value,$field,$fvalue){
$bag = $GLOBALS['baglanti'];
$sts='';
if(is_array($set)){
for ($i=0; $i < count($set); $i++) {
$sts.=$set[$i]."='".$value[$i]."',";
}
$sts=rtrim($sts,",");
}else{
$sts=$set."='".$value."'";
}
$sql = "UPDATE $table set $sts WHERE $field='$fvalue'";
echo $sql; // you can comment this line out when you are sure the SQL is good
$val = $bag->exec($sql);
return $val;
}
?>
update.php
Small amendment here just so you know whats actually being returned from the function is a count and not a row ID. It could also be FALSE, indicating an error occured in the Updt() function in the query.
<?php
include("database.php");
$fields = array();
$values=array();
$fvalue=$_POST['id'];
$table=$_POST['table'];
foreach ($_POST as $key => $value) {
if( $key!='table' && $key!='id' && $key!='alan'){
if( strpos($key,"date")){
$datet=new DateTime($value);
$value=$datet->format('Y-m-d');
}
array_push($fields,$key);
array_push($values,$value);
}
}
$alan=$_POST['alan'];
//$ID=Updt($table,$fields,$values,$alan,$fvalue);
// this is not an ID it is a coumt of the number or rows
// updated by the Updt() function
$cnt = Updt($table,$fields,$values,$alan,$fvalue);
if ( $cnt === FALSE ) {
// then we had an error in Updt()
print_r($baglanti->errorInfo(), true);
exit;
}
if($cnt != 0){
echo 'Rows updated = ' . $cnt;
}
?>
I have to mention this as others will if I dont. Your code is open to SQL Injection you should really be using prepared statements. Maybe you should mention this to the Programmers you mentioned. Maybe you should also not assume everything they wrote was done correctly.

Passing array of data to other page using session in PHP

I have some problem passing array of data in Php using session:
In my class, I have this function:
public function check_dupID($id)
{
$this->stmt="select id from student where id='$id'";
$this->res = mysql_query($this->stmt);
$this->num_rows = mysql_num_rows($this->res);
if($this->num_rows == 1)
{
while($this->row = mysql_fetch_array($this->res))
{
$dup_id = $this->row[0];
return $dup_id;
}
}
}
This code checks for duplicate ID of a student. Now, the reason for this is that I uploaded the file in the database using ".csv" file.
Before Uploading it I put all the data in the csv file into an array. Now, I check it one by one:
//created the variable for checking
$id = $check->check_dupID($array[0]);
if($id == TRUE)
{
session_start();
$_SESSION['id']; = $id;//passing it to the next back to array again.
$redirect->page($error);
}
Now when it redirect it gives me the result of an "Array" and if I parse it using foreach it shows only one id but there is more than of that. I want to know how to display it all.
This code will return the duplicate id when it is found for the first time. If you want to return all the duplicate ids, then add them into an array using the while loop and then return it.
To do this modify your code like this:
public function check_dupID($id)
{
$this->stmt="select id from student where id='$id'";
$this->res = mysql_query($this->stmt);
$this->num_rows = mysql_num_rows($this->res);
$dup_id = array();// added here to prevent invalid argument supplied to foreach loop error if nothing is found
if($this->num_rows >1)
{
while($this->row = mysql_fetch_array($this->res))
{
$dup_id[] = $this->row[0];// adding duplicates into the array
}
return $dup_id;
}
}
This code fixes my problem:
if($id == TRUE)
{
$get_id = array();
$get_id[] = $id;
session_start();
$_SESSION['id']; = $get_id;//passing it to the next back to array again.
$redirect->page($error);
}

GET Multiple MySQL Rows, Form PHP Variables, and Put Into Json Encoded Array

I am trying to GET different rows from different columns in php/mysql, and pack them into an array. I am able to successfully GET a jason encoded array back IF all values in the GET string match. However, if there is no match, the code echos 'no match', and without the array. I know this is because of the way my code is formatted. What I would like help figuring out, is how to format my code so that it just displays "null" in the array for the match it couldn't find.
Here is my code:
include '../db/dbcon.php';
$res = $mysqli->query($q1) or trigger_error($mysqli->error."[$q1]");
if ($res) {
if($res->num_rows === 0)
{
echo json_encode($fbaddra);
}
else
{
while($row = $res->fetch_array(MYSQLI_BOTH)) {
if($_GET['a'] == "fbaddra") {
if ($row['facebook'] === $_GET['facebook']) {
$fbaddr = $row['addr'];
} else {
$fbaddr = null;
}
if ($row['facebookp'] === $_GET['facebookp']) {
$fbpaddr = $row['addr'];
} else {
$fbpaddr = null;
}
$fbaddra = (array('facebook' => $fbaddr, 'facebookp' => $fbpaddr));
echo json_encode($fbaddra);
}
}
}
$mysqli->close();
UPDATE: The GET Request
I would like the GET request below to return the full array, with whatever value that didn't match as 'null' inside the array.
domain.com/api/core/engine.php?a=fbaddra&facebook=username&facebookp=pagename
The GET above currently returns null.
Requests that work:
domain.com/api/core/engine.php?a=fbaddra&facebook=username or domain.com/api/core/engine.php?a=fbaddra&facebookp=pagename
These requests return the full array with the values that match, or null for the values that don't.
TL;DR
I need assistance figuring out how to format code to give back the full array with a value of 'null' for no match found in a row.
rather than assigning as 'null' assign null. Your full code as follows :
include '../db/dbcon.php';
$res = $mysqli->query($q1) or trigger_error($mysqli->error."[$q1]");
if ($res) {
if($res->num_rows === 0)
{
echo json_encode('no match');
}
else
{
while($row = $res->fetch_array(MYSQLI_BOTH)) {
if($_GET['a'] == "fbaddra") {
if ($row['facebook'] === $_GET['facebook']) {
$fbaddr = $row['dogeaddr'];
//echo json_encode($row['dogeaddr']);
} else {
$fpaddr = null;
}
if ($row['facebookp'] === $_GET['facebookp']) {
$fbpaddr = $row['dogeaddr'];
//echo json_encode($row['dogeaddr']);
} else {
$fbpaddr = null;
}
$fbaddra = (array('facebook' => $fbaddr, 'facebookp' => $fbpaddr));
echo json_encode($fbaddra);
}
}
}
$mysqli->close();
You can even leave else part altogether.
Check your code in this fragment you not use same names for variables:
if ($row['facebook'] === $_GET['facebook']) {
$fbaddr = $row['dogeaddr'];
//echo json_encode($row['dogeaddr']);
} else {
$fpaddr = 'null';
}
$fbaddr not is same as $fpaddr, this assign wrong result to if statement.
It was the mysql query that was the problem.
For those who come across this, and need something similar, you'll need to format your query like this:
** MYSQL QUERY **
if ($_GET['PUTVALUEHERE']) {
$g = $_GET['PUTVALUEHERE'];
$gq = $mysqli->real_escape_string($g);
$q1 = "SELECT * FROM `addrbook` WHERE `facebookp` = '".$gq."' OR `facebook` = '".$gq."'";
}
** PHP CODE **
if($_GET['PUTVALUEHERE']{
echo json_encode($row['addr']);
}

Categories