Binding Parameter PDO prepared Statement - php

I really dont know why i am having this error even after binding parameters
SQLSTATE[HY093]: Invalid parameter number: no parameters were bound
Here is my function
public function get_no_records($param){
$query = "SELECT * FROM users_tbl WHERE username = :value";
$this->query = $query;
$stmt = $this->db->prepare($query);
$stmt->bindParam(':value',$param);
$stmt->execute();
$row_num = $stmt->rowCount();
if($row_num > 0){
$this->total_rec = $row_num;
return $row_num;
}
}
The function is part of a pagination class.This is the class
<?php
class Paginator{
private $db;
public $page_no;//current page
public $limit;//record_per page
public $row_start;
public $total_rec;
public $query;
function __construct($con){
$this->db = $con;
}
//get total no of records
public function get_no_records($param){
$query = "SELECT * FROM users_tbl WHERE username = :value";
$this->query = $query;
$stmt = $this->db->prepare($query);
$stmt->bindParam(':value',$param);
$stmt->execute();
$row_num = $stmt->rowCount();
if($row_num > 0){
$this->total_rec = $row_num;
return $row_num;
}
}
public function get_data($limit,$page_no){
try {
$this->limit = $limit;
$this->page_no = $page_no;
if($this->limit == "all"){
$query = $this->query;
}
else{
$this->row_start = (($this->page_no-1) * $this->limit);
$query = $this->query . " LIMIT ". $this->row_start . "," . $this->limit;
}
$stmt = $this->db->prepare($query);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
//create an array to hold record
$results[] = $row;
}
$result = new stdClass();
$result->page_no = $this->page_no;
$result->limit = $this->limit;
$result->total_rec = $this->total_rec;
$result->data = $results;
return $result;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
public function create_links($links,$list_class){
if($this->limit == 'all'){
return '';
}
$last = ceil($this->total_rec/$this->limit);
$start = (($this->page_no - $links) > 0) ? $this->page_no - $links : 1;
$end = (($this->page_no + $links) < $last) ? $this->page_no + $links : $last;
$html = '<ul class="' . $list_class . '">';
$class = ($this->page_no == 1) ? "disabled" : "";
$previous_page = ($this->page_no == 1) ?
'<li class="' . $class . '">«</li>' :
'<li class="' . $class . '">«</li>';
$html .= $previous_page;
if($start > 1){
$html .= '<li>1</li>';
$html .= '<li class="disabled"><span>....</span></li>';
}
for($i = $start;$i<=$end;$i++){
$class = ($this->page_no == $i)? "active" : "";
$html .= '<li class="' . $class . '">' . $i . '</li>';
}
if( $end < $last){
$html .= '<li class="disabled"><span>....</span></li>';
$html .= '<li>' . $last . '</li>';
}
$class = ($this->page_no == $last)? "disabled" : "";
$next_page = ( $this->page_no == $last)?
'<li class="' . $class . '">»</li>':
'<li class="' . $class . '">»</li>';
$html .= $next_page;
$html .= '</ul>';
return $html;
}
}
?>

Thanks to you all. I have gotten where the error is coming from, its the get_data(),since that function also contains a the query,a value has to be binded as well.Here is my new code.
<?php
class Paginator{
private $db;
public $page_no;//current page
public $limit;//record_per page
public $row_start;
public $total_rec;
public $query;
function __construct($con){
$this->db = $con;
}
//get total no of records
public function get_no_records($query,$value){
$this->query = $query;
$stmt = $this->db->prepare($query);
$stmt->bindParam(':value',$value);
$stmt->execute();
$row_num = $stmt->rowCount();
if($row_num > 0){
$this->total_rec = $row_num;
return $row_num;
}
}
public function get_data($limit,$page_no,$value){
try {
$this->limit = $limit;
$this->page_no = $page_no;
if($this->limit == "all"){
$query = $this->query;
}
else{
$this->row_start = (($this->page_no-1) * $this->limit);
$query = $this->query . " LIMIT ". $this->row_start . "," . $this->limit;
}
$stmt = $this->db->prepare($query);
$stmt->bindParam('value',$value);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
//create an array to hold record
$results[] = $row;
}
if(empty($results)){
return;
}
$result = new stdClass();
$result->page_no = $this->page_no;
$result->limit = $this->limit;
$result->total_rec = $this->total_rec;
$result->data = $results;
return $result;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
public function create_links($links,$list_class){
if($this->limit == 'all'){
return '';
}
$last = ceil($this->total_rec/$this->limit);
$start = (($this->page_no - $links) > 0) ? $this->page_no - $links : 1;
$end = (($this->page_no + $links) < $last) ? $this->page_no + $links : $last;
$html = '<ul class="' . $list_class . '">';
$class = ($this->page_no == 1) ? "disabled" : "";
$previous_page = ($this->page_no == 1) ?
'<li class="' . $class . '">«</li>' :
'<li class="' . $class . '">«</li>';
$html .= $previous_page;
if($start > 1){
$html .= '<li>1</li>';
$html .= '<li class="disabled"><span>....</span></li>';
}
for($i = $start;$i<=$end;$i++){
$class = ($this->page_no == $i)? "active" : "";
$html .= '<li class="' . $class . '">' . $i . '</li>';
}
if( $end < $last){
$html .= '<li class="disabled"><span>....</span></li>';
$html .= '<li>' . $last . '</li>';
}
$class = ($this->page_no == $last)? "disabled" : "";
$next_page = ( $this->page_no == $last)?
'<li class="' . $class . '">»</li>':
'<li class="' . $class . '">»</li>';
$html .= $next_page;
$html .= '</ul>';
return $html;
}
}
?>
The query in the get_data() has a parameter of $value bounded now,before execution of the query.

I do not use bind param but the execute statement only.
public function get_no_records($param)
{
$query = "SELECT * FROM users_tbl WHERE username = :my_value;";
$this->query = $query; //What use do I have?
$stmt = $this->db->prepare($query);
$stmt->execute(array(':my_value' => $param));
$row_num = $stmt->rowCount();
if($row_num > 0)
{
$this->total_rec = $row_num;
return $row_num;
}
return 0; //Added so the function always has a return value
}
The binding of ':value' is done by creating an associative array that is only used as a parameter for the execute function.

Related

"SQL translate error: Extra placeholder" when using prepared statements

I'm trying to use prepared statements in my SQL but I can't get it working. I'm getting error "SQL translate error: Extra placeholder" when I add something like this to my code
if ($cpucooler_socket != "") {
$myArray = explode(',', trim($cpucooler_socket));
for ($i = 0; $i < count($myArray); $i++) {
if(count($myArray)>1) {
$socket = $myArray[$i];
if ($i === 0) {
$query .= " AND (socket LIKE ?";
$query_params[] = '%' . $socket . '%';
} else if ($i === count($myArray) - 1) {
$query .= " OR socket LIKE ?)";
$query_params[] = '%' . $socket . '%';
} else {
$query .= " OR socket LIKE ?";
$query_params[] = '%' . $socket . '%';
}
} else {
$query .= " AND socket LIKE ?";
$query_params[] = '%' . $socket . '%';
}
}
}
What am I doing wrong? What is the right syntax that I should be using in this case? If I don't use the for loop and I add only for example this instead:
$query .= " AND socket LIKE ?";
$query_params[] = '%' . $myArray[0] . '%';
then it's working fine. Here is my full code if it helps:
public function getCompatibleMb($case_format_dosky, $cpu_socket, $ram_typ, $pocet_ram, $intel_socket, $amd_socket, $select_after_id, $search) {
$cpucooler_socket = null;
if(isset($intel_socket) || isset($amd_socket)){
if ($intel_socket != null && $amd_socket != null) {
$cpucooler_socket = $intel_socket.", ".$amd_socket;
} else if($intel_socket != null) {
$cpucooler_socket = $intel_socket;
} else if ($amd_socket != null){
$cpucooler_socket = $amd_socket;
}
} else {
$cpucooler_socket = null;
}
$query_params = array();
$query = "SELECT id encryptid, id,produkt,vyrobca,dostupnost,cena,socket,series,chipset,form_factor,bluetooth,wifi,rgb,m2,sata3,sietova_karta,zvukova_karta,pci_express_3_0,pci_express_4_0,pci_express_5_0,ram_type,ram_slots,rezim_ram,max_mhz_ram,mosfet_coolers,crossfire_support,sli_support,raid_support,audio_chipset,audio_channels,ext_connectors,int_connectors,max_lan_speed,pci_x16_slots,pci_x4_slots,pci_x1_slots,m2_ports,usb_2_0,usb_3_2_gen_1,usb_3_1_gen_2,usb_3_2_gen_2,sata_3_ports,img_count,produkt_number,vyrobca_url FROM mb_list WHERE dostupnost=1";
if ($cpu_socket != "") {
$query .= " AND socket = ?";
$query_params[] = $cpu_socket;
} else {
if ($cpucooler_socket != "") {
$myArray = explode(',', trim($cpucooler_socket));
for ($i = 0; $i < count($myArray); $i++) {
if(count($myArray)>1) {
$socket = $myArray[$i];
if ($i === 0) {
$query .= " AND (socket LIKE ?";
$query_params[] = '%' . $socket . '%';
} else if ($i === count($myArray) - 1) {
$query .= " OR socket LIKE ?)";
$query_params[] = '%' . $socket . '%';
} else {
$query .= " OR socket LIKE ?";
$query_params[] = '%' . $socket . '%';
}
} else {
$query .= " AND socket LIKE ?";
$query_params[] = '%' . $socket . '%';
}
}
}
}
if ($ram_typ != "") {
$query .= " AND ram_type = ?";
$query_params[] = $ram_typ;
}
if ($pocet_ram != "") {
$query .= " AND ram_slots >= ?";
$query_params[] = $pocet_ram;
}
if($case_format_dosky !="") {
$myArray = explode(',', trim($case_format_dosky));
for ($i = 0; $i < count($myArray); $i++) {
if(count($myArray)>1) {
$formfactor = trim($myArray[$i]);
if ($i === 0) {
$query .= " AND (form_factor = ?";
$query_params[] = $formfactor;
} else if ($i === count($myArray) - 1) {
$query .= " OR form_factor = ?";
$query_params[] = $formfactor;
} else {
$query .= " OR form_factor = ?)";
$query_params[] = $formfactor;
}
} else {
$query .= " AND form_factor LIKE ?";
$query_params[] = '%' . $formfactor . '%';
}
}
}
if ($select_after_id != "") {
$decrypted = $this->McryptServices->decryptData($select_after_id);
$query .= " AND id > ?";
$query_params[] = $decrypted;
}
if ($search != "") {
$new_search = str_replace(" ", "%",$search);
$query .= " AND produkt LIKE ?";
$query_params[] = '%'.$new_search.'%';
}
$query .= " LIMIT 32";
$vytah = $this->Database->query($query, $query_params)->fetchAll();
$arr[] = $vytah;
foreach ($arr[0] as $key => $value) {
$arr[0][$key]->{'encryptid'} = $this->McryptServices->encryptData($arr[0][$key]->{'id'});
}
return json_encode($arr);
}
This is the response after an error:
"line":225,"args":[["string","SELECT id encryptid, id,produkt,vyrobca,dostupnost,cena,socket,series,chipset,form_factor,bluetooth,wifi,rgb,m2,sata3,sietova_karta,zvukova_karta,pci_express_3_0,pci_express_4_0,pci_express_5_0,ram_type,ram_slots,rezim_ram,max_mhz_ram,mosfet_coolers,crossfire_support,sli_support,raid_support,audio_chipset,audio_channels,ext_connectors,int_connectors,max_lan_speed,pci_x16_slots,pci_x4_slots,pci_x1_slots,m2_ports,usb_2_0,usb_3_2_gen_1,usb_3_1_gen_2,usb_3_2_gen_2,sata_3_ports,img_count,produkt_number,vyrobca_url FROM mb_list WHERE dostupnost=1 AND (form_factor = ? OR form_factor = ? OR form_factor = ?) LIMIT 32"],["array",[["string","ATX"],["string","mATX (Micro ATX)"],["string","mITX (Mini ITX)"]]]]}

Dynamic update statement - prepared statement

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);
}

Backup MySQL tables in Laravel without third-party libraries

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);
});
}
}

two methods in a class so close in what they do

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
}

PHP unitialized string offset: 0

I decided to give PHP a try, and then bought lynda.com's essential training tutorial.
The problem is, that I get this error:
( ! ) Notice: Uninitialized string offset: 0 in
C:\wamp\www\widget_corp\includes\functions.php on line 147.
when trying to compare two values.
Can anyone help me ? :)
error in navigation function:
if($page["id"] == $selectedPage['id']){
Class content.php below:
<?php require_once("includes/connection.php"); ?>
<?php require_once("includes/functions.php");?>
<?php findSelectedPage(); ?>
<?php include("includes/header.php");?>
<table id="structure">
<tr>
<td id="navigation">
<?php echo navigation($selSubject, $selectedPage);?>
<br/>
+ Add a new subject
</td>
<td id="page">
<?php echo checkSubjOrPage();?>
<br/>
<div id="footer">Copyright 2007, Widget Corp</div>
</td>
</tr>
</table>
<?php require("includes/footer.php"); ?>
class function.php below:
<?php
//This file is the place to store all basic functions.
//NB!
//function to prevent problems with submitting values, that contains
//chars such as: "", '' etc., into the database.
function mysql_prep($value){
$magic_quotes_active = get_magic_quotes_gpc;
//i.e. php>= v4.3.0
$new_enough_php = function_exists("mysql_real_escape_string");
if($new_enough_php){
//undo any magic quotes effects so mysql_real_escape_string can do the work
if($magic_quotes_active){
$value = stripslashes($value);
}
$value = mysql_real_escape_string($value);
} else { // before PHP v4.3.0
//if magic quotes aren't already on then add slashed manually
if(!$magic_quotes_active){
$value = addslashes($value);
}
}
return $value;
}
function confirm_query($result_set){
if(!$result_set){
die("Database connection failed: " . mysql_error());
}
}
function getAllSubjects(){
global $connection;
$query = "SELECT *
FROM subjects
ORDER BY position ASC";
$subject_set = mysql_query($query, $connection);
confirm_query($subject_set);
return $subject_set;
}
function getPagesForSubject($subject_id){
global $connection;
$query = "SELECT *
FROM pages
WHERE subject_id = {$subject_id}
ORDER BY position ASC";
$page_set = mysql_query($query, $connection);
confirm_query($page_set);
return $page_set;
}
function get_subject_by_id($subject_id){
global $connection;
$query = "SELECT * ";
$query .= "FROM subjects ";
$query .= "WHERE id=" . $subject_id . " ";
$query .= "LIMIT 1";
$result_set = mysql_query($query, $connection);
confirm_query($result_set);
//REMEMBER:
//if no rows are returned, fetch_array will return false.
if($subject = mysql_fetch_array($result_set)){
return $subject;
} else {
return NULL;
}
}
function get_page_by_id($page_id){
global $connection;
$query = "SELECT * ";
$query .= "FROM pages ";
$query .= "WHERE id=" . $page_id . " ";
$query .= "LIMIT 1";
$result_set = mysql_query($query, $connection);
confirm_query($result_set);
//REMEMBER:
//if no rows are returned, fetch_array will return false.
if($page = mysql_fetch_array($result_set)){
return $page;
} else {
return NULL;
}
}
function checkSubjOrPage(){
global $selSubject;
global $selectedPage;
if(!is_null($selSubject)){
return "<h2>" . $selSubject['menu_name'] . "</h2>";
} else if(!is_null($selectedPage)){
return "<h2>" . $selectedPage['menu_name'] . "</h2>" . "<div>" . $selectedPage['content'] . "</div>";
} else {
return "<h2>" . "Select a subject or page to edit!" . "</h2>";
}
}
function findSelectedPage(){
global $selSubject;
global $selectedPage;
if(isset($_GET['subj'])){
$selSubject = get_subject_by_id($_GET['subj']);
$selectedPage = "";
} else if(isset($_GET['page'])){
$selSubject = NULL;
$selectedPage = get_page_by_id($_GET['page']);
} else {
$selectedPage = NULL;
$selSubject = NULL;
}
}
function navigation($selSubject, $selectedPage){
$output = "<ul class=\"subjects\">";
//3. Perform our database query
$subject_set = getAllSubjects();
while($subject = mysql_fetch_array($subject_set)){
$output .= "<li";
if($subject["id"] == $selSubject['id']){
$output .= " class=\"selected\"";
}
$output .= "><a href=\"content.php?subj=" . urlencode($subject["id"]) .
"\">{$subject["menu_name"]}</a></li>";
$page_set = getPagesForSubject($subject["id"]);
$output .= "<ul class=\"pages\">";
while($page = mysql_fetch_array($page_set)){
$output .= "<li";
if($page["id"] == $selectedPage['id']){
$output .= " class=\"selected\"";
}
$output .= "><a href=\"content.php?page=" . urlencode($page{"id"}) .
"\">{$page["menu_name"]}</a></li>";
}
$output .= "</ul>";
}
$output .= "</ul>";
return $output;
}
function getPositions(){
$subject_set = getAllSubjects();
$subject_counts = mysql_num_rows($subject_set);
$output = "<select name=\"position\">";
//$subject_counts + 1 b/c we are adding a subject.
for($count = 1; $count <= $subject_counts +1; $count++){
$output .= "<option value=\"{$count}\">{$count}</option>";
}
return $output . " </select>";
}
?>
here you override $selectedPage to a string or set it to null
function findSelectedPage(){
global $selSubject;
global $selectedPage;
if(isset($_GET['subj'])){
$selSubject = get_subject_by_id($_GET['subj']);
$selectedPage = "";
} else if(isset($_GET['page'])){
$selSubject = NULL;
$selectedPage = get_page_by_id($_GET['page']);
} else {
$selectedPage = NULL;
$selSubject = NULL;
}
}
And here it should be an array:
if($page["id"] == $selectedPage['id']){
function findSelectedPage(){
global $selSubject;
global $selectedPage;
if(isset($_GET['subj'])){
$selSubject = get_subject_by_id($_GET['subj']);
$selectedPage = NULL;
} else if(isset($_GET['page'])){
$selSubject = NULL;
$selectedPage = get_page_by_id($_GET['page']);
} else {
$selectedPage = NULL;
$selSubject = NULL;
}
}
function navigation($selSubject, $selectedPage){
$output = "<ul class=\"subjects\">";
//3. Perform our database query
$subject_set = getAllSubjects();
while($subject = mysql_fetch_array($subject_set)){
$output .= "<li";
if(isset($selSubject['id']) && $subject["id"] == $selSubject['id']){
$output .= " class=\"selected\"";
}
$output .= "><a href=\"content.php?subj=" . urlencode($subject["id"]) .
"\">{$subject["menu_name"]}</a></li>";
$page_set = getPagesForSubject($subject["id"]);
$output .= "<ul class=\"pages\">";
while($page = mysql_fetch_array($page_set)){
$output .= "<li";
if(isset($selectedPage['id']) && $page["id"] == $selectedPage['id']){
$output .= " class=\"selected\"";
}
$output .= "><a href=\"content.php?page=" . urlencode($page{"id"}) .
"\">{$page["menu_name"]}</a></li>";
}
$output .= "</ul>";
}
$output .= "</ul>";
return $output;
}

Categories