I new to Laravel. I've been trying to create a controller that backups tables in the form of backup_date_.sql format without using any third-party library at all, but I'm getting frustrated. I've searched and I found some code examples. I've tried to use them within my BackupsController, but things are getting more and more difficult. Any help is really appreciated. This is my code, Thanks in advance.
<?php
public function query($data, $mode = \PDO::FETCH_ASSOC)
{
$pdo = DB::connection()->getPdo();
$stmt = $pdo->query($data);
$results = $stmt->fetchAll($mode);
// $results = $stmt->fetch($mode);
return $results;
}
public function backup(Request $request)
{
if ($request->all()) {
$output = '';
foreach (request('table') as $table) {
$show_table_query = $this->query("SHOW CREATE TABLE " . stripslashes($table) . "");
foreach ($show_table_query as $show_table_row)
{
array_shift($show_table_row);
$output .= implode(", ", $show_table_row);
}
$single_result = DB::select('select * from ' . stripslashes($table));
foreach ($single_result as $key => $value)
{
$value = array_map(function($obj) {
return (array) $obj;
}, $single_result);
$keys = array_keys($value[$key]);
$val = array_values($value[$key]);
$get_keys = array_shift($keys);
$get_values = array_shift($val);
$table_column = implode(",", $keys);
// $table_value ="'" . implode("','", $val) . "'\n";
$table_value ="'" . implode("','", $val) . "'";
$output .= DB::insert(
"INSERT INTO " . stripslashes($table) . "("
. $table_column . ") VALUES(" . $table_value . ")"
);
}
}
?>
Write a
command https://laravel.com/docs/5.6/artisan#writing-commands
with SSH mysqldump -uUSERNAME -p DATABASE > backup.sql and
schedule https://laravel.com/docs/5.6/scheduling and
DONE :))
This is a function I found and later modified to export my databases including all the data and stored procedures and functions if any exists in the database. The code was written for a codeigniter application but you can easily convert it to laravel.
Codeigniter version:
<?php
if(!function_exists("export_database")){
function export_database($bkpFileName = null){
$ci =& get_instance();
$targetTables = [];
$newLine = "\r\n";
$queryTables = $ci->db->query('SHOW TABLES');
foreach($queryTables->result() as $table){
$targetTables[] = $table->Tables_in_my_db;
}
foreach($targetTables as $table){
$tableData = $ci->db->query('SELECT * FROM '.$table);
$res = $ci->db->query('SHOW CREATE TABLE '.$table);
$cnt = 0;
$content = (!isset($content) ? '' : $content) . $res->row_array()["Create Table"].";" . $newLine . $newLine;
foreach($tableData->result_array() as $row){
$subContent = "";
$firstQueryPart = "";
if($cnt == 0 || $cnt % 100 == 0){
$firstQueryPart .= "INSERT INTO {$table} VALUES ";
if($tableData->num_rows() > 1)
$firstQueryPart .= $newLine;
}
$valuesQuery = "(";
foreach($row as $key => $value){
$valuesQuery .= $ci->db->escape($value) . ", ";
}
$subContent = $firstQueryPart . rtrim($valuesQuery, ", ") . ")";
if( (($cnt+1) % 100 == 0 && $cnt != 0) || $cnt+1 == $tableData->num_rows())
$subContent .= ";" . $newLine;
else
$subContent .= ",";
$content .= $subContent;
$cnt++;
}
$content .= $newLine;
}
$content = trim($content);
//check for stored procedures
$storedProcedures = $ci->db->query("SHOW PROCEDURE STATUS WHERE Db = '{$ci->db->database}'");
if($storedProcedures->num_rows() > 0){
foreach($storedProcedures->result() as $procedure){
$data = $ci->db->query("SHOW CREATE PROCEDURE {$procedure->Name}");
if($data->num_rows() > 0){
$dropProcedureSQL = "DROP PROCEDURE IF EXISTS {$procedure->Name};";
$sqlQuery = $data->row_array()["Create Procedure"];
$sqlQuery = preg_replace("/CREATE DEFINER=.+? PROCEDURE/", "CREATE PROCEDURE IF NOT EXISTS", $sqlQuery);
$sqlQuery = "\r\n" . $sqlQuery . "//";
$content .= $newLine . $newLine . $dropProcedureSQL . $sqlQuery ;
}
}
}
//check for functions
$functions = $ci->db->query("SHOW FUNCTION STATUS WHERE Db = '{$ci->db->database}';");
if($functions->num_rows() > 0){
foreach($functions->result() as $function){
$data = $ci->db->query("SHOW CREATE FUNCTION {$function->Name}");
if($data->num_rows() > 0){
$dropFunctionSQL = "DROP function IF EXISTS {$function->Name};";
$sqlQuery = $data->row_array()["Create Function"];
$sqlQuery = preg_replace("/CREATE DEFINER=.+? FUNCTION/", "CREATE FUNCTION IF NOT EXISTS", $sqlQuery);
$sqlQuery = "\r\n" . $sqlQuery . "//";
$content .= $newLine . $newLine . $dropFunctionSQL . $sqlQuery ;
}
}
}
$dbBackupFile = FCPATH . BKP_FILE_DIR;
if(is_null($bkpFileName))
$dbBackupFile .= "{$ci->db->database}.sql";
else
$dbBackupFile .= "{$bkpFileName}.sql";
$handle = fopen($dbBackupFile, "w+");
fwrite($handle, $content);
fclose($handle);
return $dbBackupFile;
}
}
Laravel version:
<?php
if(!function_exists("export_database")){
function export_database($bkpFileName = null){
//$ci =& get_instance();
$targetTables = [];
$newLine = "\r\n";
$queryTables = DB::select(DB::raw('SHOW TABLES'));
foreach($queryTables->result() as $table){
$targetTables[] = $table->Tables_in_my_database;
}
foreach($targetTables as $table){
$tableData = DB::select(DB::raw('SELECT * FROM '.$table));
$res = DB::select(DB::raw('SHOW CREATE TABLE '.$table));
$cnt = 0;
$content = (!isset($content) ? '' : $content) . $res->row_array()["Create Table"].";" . $newLine . $newLine;
foreach($tableData as $row){
$subContent = "";
$firstQueryPart = "";
if($cnt == 0 || $cnt % 100 == 0){
$firstQueryPart .= "INSERT INTO {$table} VALUES ";
if(count($tableData) > 1)
$firstQueryPart .= $newLine;
}
$valuesQuery = "(";
foreach($row as $key => $value){
$valuesQuery .= $value . ", ";
}
$subContent = $firstQueryPart . rtrim($valuesQuery, ", ") . ")";
if( (($cnt+1) % 100 == 0 && $cnt != 0) || $cnt+1 == count($tableData))
$subContent .= ";" . $newLine;
else
$subContent .= ",";
$content .= $subContent;
$cnt++;
}
$content .= $newLine;
}
$content = trim($content);
//check for stored procedures
$storedProcedures = DB::select(DB::raw("SHOW PROCEDURE STATUS WHERE Db = '{$ci->db->database}'");
if($storedProcedures->count() > 0){
foreach($storedProcedures->result() as $procedure){
$data = DB::select(DB::raw("SHOW CREATE PROCEDURE {$procedure->Name}"));
if($data->count() > 0){
$dropProcedureSQL = "DROP PROCEDURE IF EXISTS {$procedure->Name};";
$sqlQuery = $data->row_array()["Create Procedure"];
$sqlQuery = preg_replace("/CREATE DEFINER=.+? PROCEDURE/", "CREATE PROCEDURE IF NOT EXISTS", $sqlQuery);
$sqlQuery = "\r\n" . $sqlQuery . "//";
$content .= $newLine . $newLine . $dropProcedureSQL . $sqlQuery ;
}
}
}
//check for functions
$functions = DB::select(DB::raw("SHOW FUNCTION STATUS WHERE Db = '{$ci->db->database}';"));
if($functions->count() > 0){
foreach($functions->result() as $function){
$data = DB::select(DB::raw("SHOW CREATE FUNCTION {$function->Name}");
if($data->count() > 0){
$dropFunctionSQL = "DROP function IF EXISTS {$function->Name};";
$sqlQuery = $data->row_array()["Create Function"];
$sqlQuery = preg_replace("/CREATE DEFINER=.+? FUNCTION/", "CREATE FUNCTION IF NOT EXISTS", $sqlQuery);
$sqlQuery = "\r\n" . $sqlQuery . "//";
$content .= $newLine . $newLine . $dropFunctionSQL . $sqlQuery ;
}
}
}
/*$dbBackupFile = FCPATH . BKP_FILE_DIR;
if(is_null($bkpFileName))
$dbBackupFile .= "{$ci->db->database}.sql";
else
$dbBackupFile .= "{$bkpFileName}.sql";
$handle = fopen($dbBackupFile, "w+");
fwrite($handle, $content);
fclose($handle);*/
return $content;
}
}
Note:
I have tried my best to convert the above code from codeigniter to laravel. But since I don't have running instance of laravel to test it out I'm not sure it will work
I refactored #Igor Ilic's answer to be laravel compatible and improved it a little bit, I hope it is useful :)
It is well tested with laravel 9
function ExportDatabase(array $tablesToBackup = null, string $backupFilename = null): string
{
$targetTables = [];
$newLine = "\n";
if ($tablesToBackup == null)
{
$queryTables = DB::select(DB::raw('SHOW TABLES'));
foreach ($queryTables as $table)
{
$targetTables[] = $table->Tables_in_my_database;
}
}
else
{
foreach ($tablesToBackup as $table)
{
$targetTables[] = $table;
}
}
foreach ($targetTables as $table)
{
$tableData = DB::select(DB::raw('SELECT * FROM ' . $table));
$res = DB::select(DB::raw('SHOW CREATE TABLE ' . $table))[0];
$cnt = 0;
$content = (!isset($content) ? '' : $content) . $res->{"Create Table"} . ";" . $newLine . $newLine;
foreach ($tableData as $row)
{
$subContent = "";
$firstQueryPart = "";
if ($cnt == 0 || $cnt % 100 == 0)
{
$firstQueryPart .= "INSERT INTO {$table} VALUES ";
if (count($tableData) > 1)
{
$firstQueryPart .= $newLine;
}
}
$valuesQuery = "(";
foreach ($row as $key => $value)
{
$valuesQuery .= "'$value'" . ", ";
}
$subContent = $firstQueryPart . rtrim($valuesQuery, ", ") . ")";
if ((($cnt + 1) % 100 == 0 && $cnt != 0) || $cnt + 1 == count($tableData))
{
$subContent .= ";" . $newLine;
}
else
{
$subContent .= ",";
}
$content .= $subContent;
$cnt++;
}
$content .= $newLine;
}
$content = trim($content);
if (is_null($backupFilename))
{
return $content;
}
$dbBackupFile = storage_path('backups/database/');
if (!File::exists($dbBackupFile))
{
File::makeDirectory($dbBackupFile, 0755, true);
}
$dbBackupFile .= "{$backupFilename}.sql";
$handle = fopen($dbBackupFile, "w+");
fwrite($handle, $content);
fclose($handle);
return $content;
}
I created this specifically to clone WordPress subsite tables from one database to another (hence, the $prefix parameter). Leaving the default value of $prefix ('%') will get all tables in the source database.
This has been tested with Laravel 9.x.
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Collection;
class CloneService
{
public function clone(string $sourceDb, string $destDb, string $prefix): void
{
$tables = $this->getTables($sourceDb, $prefix);
if ($tables->count() > 0) {
$tables->each(function ($table) use ($sourceDb, $destDb) {
$success = DB::statement("CREATE TABLE {$destDb}.{$table} LIKE {$sourceDb}.{$table};");
if ($success) {
$this->insertData($sourceDb, $destDb, $table);
}
});
}
}
public function getTables(string $dbName, string $prefix = '%'): Collection
{
$tables = collect();
// Escape underscores
$prefix = str_replace('_', '\_', $prefix);
collect(DB::select("SHOW TABLES FROM {$dbName} LIKE '{$prefix}%';"))
->each(function ($result) use (&$tables) {
// Convert the stdClass to an array, and get the first element
$table = current((array)$result);
$tables->push($table);
});
return $tables;
}
protected function insertData(string $sourceDb, string $destDb, string $table): void
{
$tableData = DB::select(DB::raw("SELECT * FROM {$sourceDb}.{$table};"));
collect($tableData)->each(function ($row) use ($destDb, $table) {
$rowData = get_object_vars($row);
// Create a comma-separated string of the columns
$columns = implode(',', array_keys($rowData));
$values = array_values($rowData);
// Create a comma-separated string of "?'s"
$prep = implode(',', array_fill(0, count($values), '?'));
$query = "INSERT INTO {$destDb}.{$table} ({$columns}) VALUES ({$prep})";
DB::insert($query, $values);
});
}
}
Related
I am generating my MYSQL update statement dynamically in PHP. As I want my application to be secure to SQL injections I want to use the prepared statement function. But as I'm pretty experienced I'm struggling to do so. Below my code so far:
function sqlUpdate($tablename)
{
$connect = sqlConnect();
$updateString = "UPDATE " . $tablename . " SET ";
$columnname = getColumnname($tablename, false, true);
for ($k=0; $k<count($columnname, COUNT_RECURSIVE); $k++)
{
if ($k+1 < count($columnname, COUNT_RECURSIVE))
{
$updateString .= $columnname[$k] . " = '" . mysqli_real_escape_string($connect, $_POST[$columnname[$k]]) . "', ";
}
else
{
$updateString .= $columnname[$k] . " = '" . mysqli_real_escape_string($connect, $_POST[$columnname[$k]]) . "' WHERE " . $columnname[0] . " = '" . mysqli_real_escape_string($connect, $_POST[$columnname[0]]) . "';";
}
}
if(mysqli_query($connect, $updateString))
{
echo "Daten wurden erfolgreich aktualisiert! </br>";
}
else
{
echo "Es ist ein Fehler aufgetreten... </br>";
}
mysqli_close($connect);
}
My code is working fine at the moment but I'm not managing to get it to work with prepared statements. I hope my question is not too stupid. Can somebody share some thoughts how to realize it with my code or do I have to completly overthink my approach?
Sorry again for my noob question...
Thanks!
Thanks to everybody who answered I managed to get it to work. I used the call_user_func_array function and can now generate the prepared statements for UPDATE and INSERT in one function:
function preparedStatement($tableName, $action)
{
$connect = sqlConnect();
$stmt = $connect->stmt_init();
$columnname = getColumnname($tableName, false, true);
for ($k=0; $k<count($columnname, COUNT_RECURSIVE); $k++)
{
$fielddata[] = $columnname[$k];
$fieldvalue[] = $_POST[$columnname[$k]];
}
if ($action == "insert")
{
$fieldvalue[0] = " ";
}
$fieldvalue_join = implode(',', array_map('addquote', $fieldvalue));
$fieldvalue = explode(",",$fieldvalue_join);
$valueCount = count($fieldvalue);
$question_mark = array();
for($i=0; $i<$valueCount; $i++)
{
$question_mark[] = '?';
}
$join_question_mark = implode(",", $question_mark);
$types = '';
foreach($fieldvalue as $param)
{
if(is_int($param))
{
$types .= 'i'; //integer
}
elseif (is_float($param))
{
$types .= 'd'; //double
}
elseif (is_string($param))
{
$types .= 's'; //string
}
else
{
$types .= 'b'; //blob and unknown
}
}
if ($action == "insert")
{
$insertString = "INSERT INTO ".$tableName."(".implode(",",$fielddata).") VALUES (".$join_question_mark.");";
$stmt->prepare($insertString);
$bind_names[] = $types;
}
elseif ($action == "update")
{
$updateString = "UPDATE " . $tableName . " SET ";
for ($k=0; $k<count($columnname, COUNT_RECURSIVE); $k++)
{
if ($k+1 < count($columnname, COUNT_RECURSIVE))
{
$updateString .= $columnname[$k] . " = ?, ";
}
else
{
$updateString .= $columnname[$k] . " = ? WHERE " . $columnname[0] . " = '" . mysqli_real_escape_string($connect, $_POST[$columnname[0]]) . "';";
}
}
$stmt->prepare($updateString);
$bind_names[] = $types;
}
for ($i=0; $i<count($fieldvalue); $i++)
{
$bind_name = 'bind' . $i;
$$bind_name = $fieldvalue[$i];
$bind_names[] = &$$bind_name;
}
call_user_func_array(array($stmt,'bind_param'),$bind_names);
if($stmt->execute())
{
$insert_id=$stmt->insert_id;
$stmt->close();
return $insert_id;
}
else
{
echo "Fehler beim Ausführen der Aktion...";
}
}
function addquote($str)
{
if($str[0]=="'" || $str[0]=='"' && $str[strlen($str)-1]=="'" || $str[strlen($str)-1]=="'" )
{
$str=substr($str,1);
$str=substr($str,0,-1);
}
return sprintf("%s", $str);
}
I am trying to save my data coming from my localhost database to our live server database using PHP. I am getting a successful response but whenever I try to check the our live database server there is no data in it or the data was not inserted or updated.
Also the response I get is this "Import successful! Found a total of 4 records in patient.file" even though the file I am importing is only to data.
Here is my code:
<?php
//============FUNCTIONS=================
function export_table($target_table,$sdate,$edate,$station){
$i = mysql_num_rows(mysql_query("DESCRIBE $target_table"));
$get_columns = mysql_query("SHOW COLUMNS FROM " . $target_table);
while($row_columns = mysql_fetch_array($get_columns)){
$column_name = $row_columns['Field'] . "|";
$csv_output .= $column_name;
}
$csv_output = rtrim($csv_output, "|");
$csv_output .= "\r\n";
$values = mysql_query("SELECT * FROM ".$target_table." WHERE
dateEncoded >= '2017-07-01' and dateEncoded <= '2017-07-07'");
while ($rowr = mysql_fetch_row($values)) {
for ($j=0;$j<$i;$j++) {
if($rowr[$j] == NULL){$rowr[$j] = "NULL";}
if($j==($i-1)){$csv_output .= str_replace(array("\n", "\r"), '', $rowr[$j]);
}else{$csv_output .= str_replace(array("\n", "\r"), '', $rowr[$j])."|";}
}// end for
$csv_output .= "\r\n";
}// end while
return $csv_output;
}// end function export_table
//========CREATION OF THE FILE===========================
include_once "../ewcfg8.php";
include_once "../dbcon.php";
date_default_timezone_set('Asia/Manila');
ini_set('memory_limit', '-1');
set_time_limit(0);
// $startdate = '2017-06-01';
// $enddate = '2017-07-07'; ;
// $defaulStation = $_POST['defaultStation'];
$tables = array('patient',
'tb_adr',
'tb_case',
'tb_casecomment',
'tb_comorbidity',
'tb_consilium',
'tb_consultations',
'tb_contact',
'tb_pe',
'tb_prescript',
'tb_prevcase',
'tb_resultculture',
'tb_resultgx',
'tb_resultdst',
'tb_resultdstdrug',
'tb_resulthiv',
'tb_resultxray',
'tb_symptom',
'tb_resultdssm',
'tb_dot');
//put tables in an array within an array(make a multi-dimensional array)
$dl_table = array();
foreach ($tables as $table) {
$content = export_table($table,$startdate,$enddate,$defaulStation);
$dl_table[$table] = $content;//multi-dimensional array
}
//#mysql_close($con); //close localhost connection
//=========INSERTING VALUES TO DATABASE===============
//===============Open New Connection And Connect to Live Database========
$dbhost = "http/mywebsite.example";
$localport = "3306";
$dbuser = "user";
$dbpass = "12345";
$dbname = "myonlinedb";
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn ) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $conn);
$fieldseparator = "|";
$lineseparator = "\n";
foreach ($tables as $table) {
$databasetable = $table;
$csvfile = $dl_table[$table]; //variable that hold the multi-dimensional array
$lines = 0;
$header = 0;
$queries = "";
$linearray = array();
$columns = array();
//====================================Get the Columns (First line in the CSV)===================================
while(($header == 0 && $columns = fgetcsv(${$table},0,"|")) != false){
$header = 1;
$num_columns = count($columns);
$list_columns = "";
for ($c=0; $c < $num_columns; $c++) {
$list_columns .= "`" . $columns[$c] . "`" . ", ";
}
$list_columns = substr($list_columns,0,-2);
//echo $list_columns . "<br /><br />";
break;
}// close while(($columns = fgetcsv($file,0,"|")) !== false && $header == 0)
//====================================Get the contents of the CSV===================================
//Set the header to skip the first row
$header = 0;
//opening the csv file
// $size = filesize($csvfile);
// echo $size;
// if(!$size) {echo "File is empty.\n";}
// $csvcontent = fread($file,$size);
// fclose($file);
//foreach(split($lineseparator,$csvcontent) as $line)
foreach(explode($lineseparator,$csvfile) as $line) {
//if($header == 0){
//$header = 1;
//}else{
$lines++;
$line = trim($line," \t");
$line = str_replace("\r","",$line);
/************************************
This line escapes the special character. remove it if entries are already escaped in the csv file
************************************/
$line = str_replace("'","\'",$line);
/*************************************/
$linearray = explode($fieldseparator,$line);
//*********get the csvID id and the columns in the db table to know if an insert or update will be performed****************
if ($databasetable == "patient"){
$csvID = $linearray[2];
$searchField = "patientID";
}else if($databasetable == "tb_case"){
$csvID = $linearray[0];
$searchField = "caseID";
}else if($databasetable == "tb_resultdstdrug"){
$csvID = $linearray[1]. $linearray[2];
$searchField = "CONCAT(caseIDplus, series)";
}else{
$csvID = $linearray[1]. $linearray[2];
$searchField = "CONCAT(caseID, series)";
}
//***********convert id of each row to 0*******************************
if($databasetable != "tb_case"){$linearray['0'] = '';}
//*****************search the csvID in the database************************************
$searchID = mysql_query("SELECT * FROM $databasetable WHERE $searchField = '$csvID'");
//******************count the number of columns in csv and the db table**************
$countcsv = count($linearray);
$countColumns = $num_columns;
//$countColumns = mysql_num_fields($searchID);
//****************count if the csvID exists in the database********************************
$countResults = mysql_num_rows($searchID);
//*************************get the date encoded in the csv and db table***************
$row = mysql_fetch_assoc($searchID);
$db_dateEncoded = $row['dateEncoded'];
if($databasetable == "tb_dot"){$csv_dateEncoded = $linearray[($countcsv-3)];}
else{$csv_dateEncoded = $linearray[($countcsv-2)];}
//*****************if else statement for checking number of fields****************************************
if ($countResults > 0){
//if a result was found, UPDATE the row
if ($csv_dateEncoded>$db_dateEncoded){
// if table is dot, delete all dot of the tb_case
$query = "UPDATE $databasetable SET ";
$i = 1;
while ($i < $countColumns){
$meta = mysql_fetch_field($searchID, $i);
if($linearray[$i] == "NULL"){
$query .= $columns[$i] . "=" . $linearray[$i];
//if last field
if($i == ($countColumns-1)){$query .= " WHERE $searchField = '$csvID';";}else{$query .= ",";}
}else{
$query .= $columns[$i] . "='" . $linearray[$i];
//if last field
if($i == ($countColumns-1)){$query .= "' WHERE $searchField = '$csvID';";}else{$query .= "',";}
}//end if($linearray[$i] == "NULL")
$i = $i + 1;
}//close while ($i < $countColumns)
}// end if($csv_dateEncoded>=$db_dateEncoded)
}else{//if no id was found, INSERT a new row
//$query = "INSERT INTO $databasetable VALUES(";
if($databasetable == 'patient'){$query = "INSERT INTO $databasetable VALUES(";}
else{$query = "INSERT INTO $databasetable ($list_columns) VALUES(";}
$i = 0;
while ($i < $countColumns){
if($linearray[$i] == "NULL"){
$query .= $linearray[$i];
if($i == ($countColumns-1)){$query .= ");";}else{$query .= ",";}
}else{
$query .= "'" . $linearray[$i];
if($i == ($countColumns-1)){$query .= "');";}else{$query .= "',";}
}
$i = $i + 1;
}//end While
}// close if ($countResults > 0){
//$queries .= $query . "\n";
//print "$query<br />";
#mysql_query($query);
//}//close if($header == 0)
}// close foreach(split($lineseparator,$csvcontent) as $line)
//unlink("data_uploading/files/" . $user . "/" . $databasetable . ".csv");
echo "Import successful! Found a total of $lines records in $table.file.\n<br /><br />";
//mysql_close($conn);
#mysql_close($con);
//====================================Get the Contents===================================
}//close foreach ($tables as $table)
//rmdir("data_uploading/files/" . $user);
//==========END OF INSERTING VALUES TO DATABASE ===========
This is bizarre. I am working on a new website using WAMP on my pc and I copy and pasted the database functions I created from another site I worked on.
Below is the function. On this new site I'm getting an error (Notice: Undefined offset: 0) whenever there is nothing that matches in the database. But, on the other site (which is hosted externally) I never get that error (never have and I just tested it specifically to make sure).
Obviously, I could just put the "return $rows[0]" in an if statement to prevent this. But, I would like to know what is causing the problem in case I need to make some changes to the old site! I'm kind of worried!
There's also another difference. On the new site I get an error when the $order is NULL, saying that $s3 is undefined. Again, I can fix it easily by just defining it along with $s1 and $s2 at the beginning. But, it works fine on my other site and has for a long time. What on earth is the difference??
function get_row5($table, $field, $where1, $value1, $where2=NULL, $value2=NULL, $where3=NULL, $value3=NULL, $where4=NULL, $value4=NULL, $where5=NULL, $value5=NULL, $order=NULL) {
$rows = array();
global $conn;
connect();
$s1 = "SELECT $field FROM $table WHERE $where1" . '=' . "'$value1'";
$s2 = "";
if ($where2 != NULL) {
if ($value2 == NULL) {
$s2 = " and $where2 is NULL";
} else {
$s2 = " and $where2" . ' = ' . "'$value2'";
}
}
if ($where3 != NULL) {
if ($value3 == NULL) {
$s2 .= " and $where3 is NULL";
} else {
$s2 .= " and $where3" . ' = ' . "'$value3'";
}
}
if ($where4 != NULL) {
if ($value4 == NULL) {
$s2 .= " and $where4 is NULL";
} else {
$s2 .= " and $where4" . ' = ' . "'$value4'";
}
}
if ($where5 != NULL) {
if ($value5 == NULL) {
$s2 .= " and $where5 is NULL";
} else {
$s2 .= " and $where5" . ' = ' . "'$value5'";
}
}
if ($order != NULL) {
$s3 = " ORDER BY $order LIMIT 1";
}
$sql = $s1 . $s2 . $s3;
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
mysqli_free_result($result);
$conn->close();
return $rows[0];
}
You are geting this error because there is no row return from query you can overcome with following code
function get_row5($table, $field, $where1, $value1, $where2=NULL, $value2=NULL, $where3=NULL, $value3=NULL, $where4=NULL, $value4=NULL, $where5=NULL, $value5=NULL, $order=NULL) {
$rows = array();
global $conn;
connect();
$s1 = "SELECT $field FROM $table WHERE $where1" . '=' . "'$value1'";
$s2 = "";
$s3 = "";
if ($where2 != NULL) {
if ($value2 == NULL) {
$s2 = " and $where2 is NULL";
} else {
$s2 = " and $where2" . ' = ' . "'$value2'";
}
}
if ($where3 != NULL) {
if ($value3 == NULL) {
$s2 .= " and $where3 is NULL";
} else {
$s2 .= " and $where3" . ' = ' . "'$value3'";
}
}
if ($where4 != NULL) {
if ($value4 == NULL) {
$s2 .= " and $where4 is NULL";
} else {
$s2 .= " and $where4" . ' = ' . "'$value4'";
}
}
if ($where5 != NULL) {
if ($value5 == NULL) {
$s2 .= " and $where5 is NULL";
} else {
$s2 .= " and $where5" . ' = ' . "'$value5'";
}
}
if ($order != NULL) {
$s3 = " ORDER BY $order LIMIT 1";
}
$sql = $s1 . $s2 . $s3;
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
mysqli_free_result($result);
$conn->close();
if(count($rows))
return $rows[0];
else
return $rows; //<---empty row
}
I have the following code but i am not sure how to check if insert is success. execute returns resource id. I would like to check if success and return all errors on fail.
public function persist()
{
$update = FALSE;
if(!is_array($this->tablePrimaryKey)) {
if(!empty($this->fieldVals[$this->tablePrimaryKey])) {
$update = true;
}
}
if ($update) {
$sql = "UPDATE " . $this->tableName . " SET ";
$binds = [];
foreach ($this->fieldVals as $key=>$val) {
if ($key != $this->tablePrimaryKey) {
if(in_array($key, $this->DATE_IDS)) {
$sql .= '"' . strtoupper($key) . '" = sysdate,';
} else {
$bind = 't_' . $key;
$binds[$bind] = $val;
$sql .= '"' . strtoupper($key) . '" = :' . $bind . ',';
}
}
}
$sql = substr($sql,0,-1);
$sql .= " WHERE " . $this->tablePrimaryKey . " = '" . $this->fieldVals[$this->tablePrimaryKey] ."'";
} else {
$binds = $fields = $date_fields = [];
if(!empty($this->tablePrimaryKey) && !is_array($this->tablePrimaryKey)) {
$this->fieldVals[$this->tablePrimaryKey] = $this->generateNewPrimaryKey();
}
foreach ($this->fieldVals as $key=>$val) {
$bind = ':t_' . $key;
if (in_array($key, $this->DATE_IDS)) {
$date_fields[] = strtoupper($key);
} else {
$binds[$bind] = $val;
$fields[] = strtoupper($key);
}
}
$sql = 'INSERT INTO ' . $this->tableName . '("' . implode('","', $fields);
if(count($date_fields) >0) {
$sql .= '","';
$sql .= implode('","', $date_fields);
}
$sql.='") VALUES (' . implode(',', array_keys($binds));
if(count($date_fields) >0) {
$cnt=0;
foreach($date_fields as $date) {
$cnt++;
if(preg_match('/NULL/i', $this->fieldVals[strtolower($date)], $result)) {
$sql .= ",NULL";
} elseif(isset($this->fieldVals[strtolower($date)])) {
$sql .= ",TO_DATE('" . (new DateTime($this->fieldVals[strtolower($date)]))->format("Y-M-d H:i:s") . "', 'yyyy/mm/dd hh24:mi:ss')";
} else {
$sql .= ",sysdate";
}
}
}
$sql .= ')';
}
$this->oiDb->parse($sql, $binds);
return $this->oiDb->execute();
}
I run $result = $oiRequests->hydrate($reportingRequest)->persist();. $reportingRequest is key,value pair of columns/values. $result contains resource id. $oiRequests is my model.
I have tried
$num_rows = oci_fetch_assoc ($result);
print_r($num_rows);
returns
Warning: oci_fetch_assoc(): ORA-24374: define not done before fetch or execute and fetch in /var/SP/oiadm/docroot/dev/uddins/requestportal/requestportal_ajax.php on line 65
Most of the OCI functions return false on error. This means you can do a simple check on the return value and, if it's false, call oci_error().
For the specific case of checking if an INSERT statement worked you can reference the example code for oci_commit(). The relevant part of that example is duplicated here:
// The OCI_NO_AUTO_COMMIT flag tells Oracle not to commit the INSERT immediately
// Use OCI_DEFAULT as the flag for PHP <= 5.3.1. The two flags are equivalent
$r = oci_execute($stid, OCI_NO_AUTO_COMMIT);
if (!$r) {
$e = oci_error($stid);
trigger_error(htmlentities($e['message']), E_USER_ERROR);
}
I have this class that has these two methods that are so closely related to the each other. I do not want to pass the flags so I kept them separate. I was wondering if there is a way to rewrite it so that I do not have to repeat so closely!
class Test extends Controller
{
public static function nonFormattedData($param)
{
$arr = array();
if (is_array($param)) {
$i = 0;
$sql = "
select *
from table1
where
";
if (isset($param['startDate'])) {
$sql .= " date_created between ? AND ?";
$arr[] = $param['startDate'];
$arr[] = $param['endDate'];
$i++;
}
if (isset($param['amount']) && !empty($param['amount'])) {
if ($i > 0) $sql .= " AND ";
$sql .= " balance= ?";
$arr[] = $param['amount'];
$i++;
}
if (isset($param) && !empty($param['amount'])) {
if ($i > 0) $sql .= " AND ";
$sql .= " balance= ?";
$arr[] = $param['amount'];
$i++;
}
if (isset($param['createdBy']) && !empty($param['createdBy'])) {
if ($i > 0) $sql .= " AND ";
$sql .= " column2 like '%Created By: " . $param['createdBy'] . "%'";
}
$sql .= ' group by id.table1 ';
$rs = Query::RunQuery($sql, $arr);
foreach ($rs as $row) {
$records = new Account();
$results[] = $records;
}
return $results;
}
}
public static function formattedData($serArray, $orderBy = "giftcardaccount_id desc", $offset = 0, $limit = 10)
{
$arr = array();
if (is_array($param)) {
$i = 0;
$sql = "
select *
from table1
where
";
if (isset($param['startDate'])) {
$sql .= " date_created between ? AND ?";
$arr[] = $param['startDate'];
$arr[] = $param['endDate'];
$i++;
}
if (isset($param['amount']) && !empty($param['amount'])) {
if ($i > 0) $sql .= " AND ";
$sql .= " balance= ?";
$arr[] = $param['amount'];
$i++;
}
if (isset($param) && !empty($param['amount'])) {
if ($i > 0) $sql .= " AND ";
$sql .= " balance= ?";
$arr[] = $param['amount'];
$i++;
}
if (isset($param['createdBy']) && !empty($param['createdBy'])) {
if ($i > 0) $sql .= " AND ";
$sql .= " column2 like '%Created By: " . $param['createdBy'] . "%'";
}
$sql .= ' group by id.table1 ';
$rs = Query::RunQuery($sql, $arr);
return array("data" => $rs);
}
}
}
Why not have one method, but with an optional formatting options object/array?
public static function getData($params, $formatting = null) {
// continue as normal, adding formatting if it's there
}