I've pieced together some code I've gleaned from the internet: I'm trying to scan a directory to insert file names and index into MariaDB table. My last hurdle it seems is this PDO error: PDO::exec() expects exactly 1 parameter, 2 given on line 55. I've tagged line(55) with '//error thrown here'.
My novice guess is it doesn't like the parameters escaped in []??
As noted above novice here...
Any insight/help is greatly appreciated. Thanks in advance.
<?php
$host = 'localhost';
$dbname = 'dirdb';
$username = 'root';
$password = '';
// Create connection
try {
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$dir = './recipes';
$GLOBALS['I'] = 0; // root folder given index 0
function dirToArray( $dir , $parent) {
$result = array();
$cdir = scandir($dir);
foreach ($cdir as $key => $value) {
if (!in_array($value, array(".", ".."))) {
if (is_dir($dir . DIRECTORY_SEPARATOR . $value)){
$result[$value] = [++$GLOBALS['I']]; // add folder index
$result[$value][] = $parent; // add parent folder index
$result[$value][] = dirToArray($dir . DIRECTORY_SEPARATOR . $value, $GLOBALS['I']);
} else {
$result[] = $value;
}
}
}
return $result;
}
$res = dirToArray($dir, $GLOBALS['I']);
function dirToDb($res, $parentId = 0)
{global $conn;
foreach ($res as $key => $value) {
if (is_array($value)) {
$conn->exec ("insert into sp_files (path, parentId) VALUES (?, ?)", [$key, $parentId]); //error thrown here
dirToDb($value, $conn->fetch("SELECT LAST_INSERT_ID()"));
} else {
$conn->exec ("insert into sp_files (path, parentId) VALUES (?, ?)", [$value, $parentId]);
}
}
}
//$res = dirToArray($dir);
dirToDb($res);
You can't use $conn->exec() to execute a query with parameters. You have to use prepare() to create a statement, then execute the prepared statement.
There's also no $conn->fetch() method. fetch() is a method of the PDOStatement class, you can use it either with a prepared statement or the result of a query. But you don't need to perform a query to get LAST_INSERT_ID(), PDO has an insertId() method for this.
function dirToDb($res, $parentId = 0) {
global $conn;
$stmt = $conn->prepare("insert into sp_files (path, parentId) VALUES (?, ?)");
foreach ($res as $key => $value) {
$stmt->execute([$key, $parentId]);
if (is_array($value)) {
dirToDb($value, $stmt->insertId);
}
}
}
Related
I have a custom class that takes a sql connection as a parameter. I use that to populate the class, and then I'm trying to use it again to modify the results on screen. But after the first use, I can't use it anymore.
connection.php:
$conn = new mysqli('localhost', 'root', '', 'loveConnections');
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
personalityProfile.php (front end)
if (!isset($_SESSION['interests'])) {
$interests = new Interests($conn, $_SESSION['id']);
$_SESSION['interests'] = $interests;
} else {
$interests = $_SESSION['interests'];
}
interestsObject.php
class Interests {
// properties
public $conn;
public $id;
public $interestsArray = [];
public function __construct($conn, $memberId = null, $intArray = [
'basketball' => false,
'bowling' => false,
'movies' => false,
]) {
$this->conn = $conn;
$this->id = $memberId;
$this->interestsArray = $intArray;
$this->popArraySql();
}
public function popArraySql() {
$memInterests = [];
$sql = "SELECT i.interest
FROM memberInfo m
Join MemberInterestLink mi on (mi.memberID_FK = m.memberID_PK)
Join interests i on (mi.interestID_FK = i.interestID_PK)
WHERE memberID_PK = $this->id";
$result = $this->conn->query($sql);
$this->conn works perfectly here
foreach ($result as $row) {
array_push($memInterests, $row['interest']);
}
foreach ($this->interestsArray as $key => $value) {
for ($i=0; $i<sizeof($memInterests); $i++) {
if ($memInterests[$i] === $key) {
$this->interestsArray[$key] = true;
}
}
}
}
public function insertUpdateQuery() {
var_dump($this->conn);
foreach ($this->interestsArray as $key => $val) {
echo $key . "<br>";
$select = "SELECT interestID_PK from interests where interest = '" . $key . "'";
echo $select;
$result = $this->conn->query($select);
when I try and use it later though, I get a Warning: mysqli::query(): Couldn't fetch mysqli. Additionally, if I try and var_dump it, I get Warning: var_dump(): Property access is not allowed yet
var_dump($result);
if ($val === true) {
$insert = "INSERT INTO MemberInterestLink (memberID_FK, interestID_FK) VALUES ($this->id, $interestKey)";
$this->conn->query($insert);
} else {
$delete = "DELETE FROM MemberInterestLink WHERE interestID_FK = $interestKey";
$this->conn->query($delete);
}
}
}
}
I never close the connection, which is what most of the related answers suggested the cause may be. It's like my $conn variable just stops working after the first use.
$projects = array('1' => $link1, '2' => $link2);
function server_status($projects) {
foreach ($projects as $server) {
$api_status = ping_api($server);
if ($api_status == 1) {
$json = json_decode(file_get_contents($server), true);
foreach ($json as $obj) {
if ($obj['online'] < 1) {
// OFFLINE
return -1;
}
else {
// ONLINE
return $obj['online'];
}
}
} else {
// MAINTENANCE
return 0;
}
}
}
function cache_status($data) {
echo $data;
$servername = "localhost";
$username = "root";
$password = "";
try {
$conn = new PDO("mysql:host=$servername;dbname=test", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
foreach ($data as $status) {
// server id + status
$sql = "UPDATE projects SET status=:status WHERE id=:server_id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':status', $status, PDO::PARAM_INT);
$stmt->bindParam(':server_id', 1, PDO::PARAM_INT);
$stmt->execute();
}
}
$problem = array(server_status($projects));
print_r($problem);
My problem is, when I print_r the variable $problem it should return two results in array, since there are two results but it only returning the first result from array as an .. example: Array ( [0] => 260 )
IF anyone is kind enough to look at my code and tell me what I am doing wrong, I would be very greatful
You are using return statement inside your loop that is why it breaks your loop on first iteration and returns what ever you have mentioned to the original call of function. To resolve this issue you need to collect the response from each iteration in array and in the end of function return your response for each iteration something like
function server_status($projects) {
$response= array();
$status = 0; // default status
foreach ($projects as $server) {
$api_status = ping_api($server);
if ($api_status == 1) {
$json = json_decode(file_get_contents($server), true);
foreach ($json as $obj) {
if ($obj['online'] < 1) {
// OFFLINE
$status= -1;
}
else {
// ONLINE
$status = $obj['online'];
}
}
}
$response[] = array('server'=>$server,'status'=>$status);
}
return $response;
}
The function is pretty straightforward:
The variables: $table is the table which the update is taking place
and $fields are the fields in the table,
and $values are generated from a post and put into the $values array
and $where is the value of the id of the index field of the table
and $indxfldnm is the index field name
function SQLUpdate($table,$fields,$values,$where,$indxfldnm) {
//Connect to DB
$dbaddr = DB_HOST;
$dbusr = DB_USER;
$dbpwd = DB_PASSWORD;
$dbname = DB_DATABASE;
$db = new PDO('mysql:host='.$dbaddr .';dbname='.$dbname.';charset=UTF8', $dbusr, $dbpwd);
//build the fields
$buildFields = '';
if (is_array($fields)) {
//loop through all the fields
foreach($fields as $key => $field) :
if ($key == 0) {
//first item
$buildFields .= $field;
} else {
//every other item follows with a ","
$buildFields .= ', '.$field;
}
endforeach;
} else {
//we are only inserting one field
$buildFields .= $fields;
}
//build the values
$buildValues = '';
if (is_array($values)) {
//loop through all the values
foreach($values as $key => $value) :
if ($key == 0) {
//first item
$buildValues .= '?';
} else {
//every other item follows with a ","
$buildValues .= ', ?';
}
endforeach;
} else {
//we are only updating one field
$buildValues .= ':value';
}
$sqlqry = 'UPDATE '.$table.' SET ('.$buildFields.' = '.$buildValues.') WHERE `'.$indxfldnm.'` = \''.$where.'\');';
$prepareUpdate = $db->prepare($sqlqry);
//execute the update for one or many values
if (is_array($values)) {
$prepareUpdate->execute($values);
} else {
$prepareUpdate->execute(array(':value' => $values));
}
//record and print any DB error that may be given
$error = $prepareUpdate->errorInfo();
if ($error[1]) print_r($error);
echo $sqlqry;
return $sqlqry;
}
So far so good
However its not working
there is something wrong with transferring the values into the fields in a proper update statement
but I'm not so good with pdo and setting it up
a little help to fix the code to bind the parameters to the values in an update would
be greatly appreciated
Thank you
Try getting this in your function
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "UPDATE MyGuests SET lastname='Doe' WHERE id=2";
// Prepare statement
$stmt = $conn->prepare($sql);
// execute the query
$stmt->execute();
// echo a message to say the UPDATE succeeded
echo $stmt->rowCount() . " records UPDATED successfully";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
Changed Code to a different build:
This eliminated the multiple-value problem
function SQLUpdate($table,$fields,$values,$where,$indxfldnm) {
$dbdata = array();
$i=0;
foreach ($fields as $fld_nm)
{
if ($i > 0) {
$dbdata[$fld_nm] = $values[$i]; }
$i++;
} //end foreach
$buildData = '';
foreach ($dbdata as $key => $val) {
if (empty($val)) {$buildData .= '`'.$key.'` = \'NULL\', ';} else {
$buildData .= '`'.$key.'` = \''.$val.'\', ';}
}
$buildData = substr($buildData,0,-2);
$dbaddr = DB_HOST;
$dbusr = DB_USER;
$dbpwd = DB_PASSWORD;
$dbname = DB_DATABASE;
$prepareUpdate ='';
try {
$db = new PDO('mysql:host='.$dbaddr .';dbname='.$dbname.';charset=UTF8', $dbusr, $dbpwd);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec("SET CHARACTER SET utf8");
$sqlqry = 'UPDATE '.$table.' SET '.$buildData.' WHERE `'.$indxfldnm.'` = \''.$where.'\';';
$prepareUpdate = $db->exec($sqlqry);
//execute the update for one or many values
}
catch(PDOException $e)
{
$e->getMessage();
print_r($e);
}
return $sqlqry;
}
//END: SQLUpdate
I'm trying to create a simple php object to manage a mysql database through pdo. So far it connects to the database just fine and now when I try to insert a new row i get the follow error:
PHP Fatal error: Using $this when not in object context on line 37
line 37 is $STH = $this->DBH->prepare($sql);
i'm probably just using $this wrong. any help will be appreciated.
<?
class Database {
private $DBH;
//connects to the database
function __construct($host,$dbname,$user,$pass) {
try {
$this->DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
//inserts into the database
//$tableName name of the table to insert the info into
//$items is a multidimensional array of array(column name, value)
public function insert($tableName,$items){
$values = array();
$sql = "INSERT INTO $tableName(";
$valuePlaceHolder = ''; // holds the question marks at the end of the PDO sql string
foreach($items as $item){
$sql .= $item[0] . ',';
array_push($values, $item[1]);
$valuePlaceHolder .= '?,';
}
// remove the last comma from the sql statement
$sql = substr($sql,0,-1);
$valuePlaceHolder = substr($valuePlaceHolder, 0, -1);
$sql .= ") values ($valuePlaceHolder)";
echo $sql;
$STH = $this->DBH->prepare($sql);
$STH->execute($values);
}
}
?>
read this:
http://www.php.net/manual/es/language.oop5.basic.php#88665
So that you can solve your problem:
....
// remove the last comma from the sql statement
$sql = substr($sql,0,-1);
$valuePlaceHolder = substr($valuePlaceHolder, 0, -1);
$sql .= ") values ($valuePlaceHolder)";
echo $sql;
$STH = Database::DBH;
$SHT = $SHT->prepare($sql);
$STH->execute($values);
.......
I'm still learning PDO so I might of missed something but basically I'm trying to insert a row into a table and then select the generated id.
I'm not sure if it likes both queries in one pdo statement. Here is the code I'm using to execute the SQL.
public function ExecuteQuery($sql, $params = array())
{
if($this->_handle == null)
$this->Connect();
$query = $this->_handle->prepare($sql);
foreach($params as $key => $value)
{
if(is_int($value)){
$query->bindValue(':'.$key, $value, \PDO::PARAM_INT);
}else if(is_bool($value)){
$query->bindValue(':'.$key, $value, \PDO::PARAM_BOOL);
}else if(is_null($value)){
$query->bindValue(':'.$key, $value, \PDO::PARAM_NULL);
}else{
$query->bindValue(':'.$key, $value, \PDO::PARAM_STR);
}
}
$query->execute();
$x = $query->fetchAll(\PDO::FETCH_ASSOC);
var_dump($x);
return $x;
}
This function is part of a database class, $this->_handle is the PDO object.
public function Connect()
{
try {
$this->_handle = new \PDO('mysql:host='.$this->_host.';dbname='.$this->_database, $this->_username, $this->_password);
$this->_handle->setAttribute( \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION );
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
And the SQL I'm running is this:
INSERT INTO `users` (`Username`, `Password`, `PasswordSalt`, `Email`, `IsAdmin`, `LoginAttempts`, `LastLogin`, `LastLoginAttempt`, `Created`) VALUES (:username, :password, :passwordsalt, :email, :isadmin, :loginattempts, :lastlogin, :lastloginattempt, :created); SELECT LAST_INSERT_ID() as 'id'
The user is created and is there in the users table but it errors after that.
Can anyone see what am doing wrong? :)
Cheers!
I'm pretty sure the mysql driver for PDO (maybe mysql itself?) does not support multi-query prepared statements.
Instead of SELECT LAST_INSERT_ID() in your query, use Conexion::$cn->lastInsertId() after your $query->execute()
I think this is correct:
function ExecuteQuery($sql, $params = array())
{
if(Conexion::$cn== null)
Conexion::Connect();
$paramString="";
foreach($params as $k=>$v)
{
$param = " :".$k." ,";
$paramString .= $param;
}
$sql.=substr($paramString,0,-2);
$query = Conexion::$cn->prepare($sql);
foreach($params as $key => $value)
{
echo "entro";
$query->bindParam(":".$key, $value);
}
$query->execute();
$x = $query->fetchAll(\PDO::FETCH_ASSOC);
var_dump($x);
return $x;
}
public function Connect()
{
try {
$dns='dblib:host='.Conexion::$server.";dbname=".Conexion::$db.";";
Conexion::$cn = new \PDO($dns, Conexion::$user, Conexion::$passw);
Conexion::$cn->setAttribute( \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION );
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}