PDOException in PHP, no error in MySQL [closed] - php

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
This is the Query that is being run:
SELECT `fleet_pilots`.`user_id` , `pilot_tracker`.`start_time` , `fleets`.`fleet_cta`
FROM `fleet_pilots`
LEFT JOIN `fleets` ON `fleets`.`fleet_id` = `fleet_pilots`.`fleet_id`
LEFT JOIN `pilot_tracker` ON `pilot_tracker`.`user_id` = `fleet_pilots`.`user_id`
AND `pilot_tracker`.`end_time` = '0000-00-00 00:00:00'
WHERE `fleet_pilots`.`fleet_id` = '26'
AND `fleet_pilots`.`user_approved` = '1'
When I run the query in mysql I have no issues and get the results as I expect.
The problem occurs when I use the results in php:
$sql = "SELECT `fleet_pilots`.`user_id`, `pilot_tracker`.`start_time`, `fleets`.`fleet_cta`
FROM `fleet_pilots`
LEFT JOIN `fleets` ON `fleets`.`fleet_id` = `fleet_pilots`.`fleet_id`
LEFT JOIN `pilot_tracker` ON `pilot_tracker`.`user_id` = `fleet_pilots`.`user_id` AND `pilot_tracker`.`end_time` = '0000-00-00 00:00:00'
WHERE `fleet_pilots`.`fleet_id` = :fleet_id AND `fleet_pilots`.`user_approved` = '1'";
$this->db->query($sql);
$args = array(
':fleet_id' => $this->input['fleet_id'],
);
$this->db->execute($args);
$fleet_users = array();
while ( $row = $this->db->fetch_row() )
{
$fleet_users[] = $row['user_id'];
if (isset($row['start_time']) && $row['fleet_cta'])
{
$sql = "UPDATE `pilots`
SET `user_total_points` = `user_total_points` + :user_total_points, `user_points` = `user_points` + :user_points
WHERE `user_id` = :user_id";
$this->db->query($sql);
$args = array(
':user_id' => $row['user_id'],
':user_points' => $this->conf->Config['point_per_min'] * ((strtotime('now') - strtotime($row['start_time']))/60),
':user_total_points' => $this->conf->Config['point_per_min'] * ((strtotime('now') - strtotime($row['start_time']))/60),
);
$this->db->execute($args);
}
}
I get this error message:
<br />
<b>Fatal error</b>: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error' in /usr/local/apache2/vhosts/trifectas.org/htdocs/fleetmaster/libs/database.class.php:109
Stack trace:
#0 /usr/local/apache2/vhosts/trifectas.org/htdocs/fleetmaster/libs/database.class.php(109): PDOStatement->fetch(2)
#1 /usr/local/apache2/vhosts/trifectas.org/htdocs/fleetmaster/libs/common.class.php(1170): Database->fetch_row()
#2 /usr/local/apache2/vhosts/trifectas.org/htdocs/fleetmaster/libs/common.class.php(1226): Common->submit_end_fleet()
#3 /usr/local/apache2/vhosts/trifectas.org/htdocs/fleetmaster/libs/common.class.php(225): Common->process_end_fleet()
#4 /usr/local/apache2/vhosts/trifectas.org/htdocs/fleetmaster/index.php(25): Common->__construct()
#5 {main}
thrown in <b>/usr/local/apache2/vhosts/trifectas.org/htdocs/fleetmaster/libs/database.class.php</b> on line <b>109</b><br />
Line 1170 is the while ( $row = $this->db->fetch_row() ) line.
Any help is appreciated.
EDIT: The following change fixed the problem for me.
$sql = "SELECT `fleet_pilots`.`user_id`, `pilot_tracker`.`start_time`, `fleets`.`fleet_cta`
FROM `fleet_pilots`
LEFT JOIN `fleets` ON `fleets`.`fleet_id` = `fleet_pilots`.`fleet_id`
LEFT JOIN `pilot_tracker` ON `pilot_tracker`.`user_id` = `fleet_pilots`.`user_id` AND `pilot_tracker`.`end_time` = '0000-00-00 00:00:00'
WHERE `fleet_pilots`.`fleet_id` = :fleet_id AND `fleet_pilots`.`user_approved` = '1'";
$this->db->query($sql);
$args = array(
':fleet_id' => $this->input['fleet_id'],
);
$this->db->execute($args);
$row = $this->db->fetch_array();
$fleet_users = $result = array();
foreach ( $row AS $key => $value )
{
$result[$key] = $value;
}
foreach ( $result AS $row )
{
$fleet_users[] = $row['user_id'];
if ( isset($row['start_time']) && $row['fleet_cta'] )
{
$sql = "UPDATE `pilots`
SET `user_total_points` = `user_total_points` + :user_total_points, `user_points` = `user_points` + :user_points
WHERE `user_id` = :user_id";
$this->db->query($sql);
$args = array(
':user_id' => $row['user_id'],
':user_points' => $this->conf->Config['point_per_min'] * ((strtotime('now') - strtotime($row['start_time']))/60),
':user_total_points' => $this->conf->Config['point_per_min'] * ((strtotime('now') - strtotime($row['start_time']))/60),
);
$this->db->execute($args);
}
}
This is my PDO wrapper.
<?php
defined('IN_APP') || die('Hands off!');
class Database
{
protected $connection;
protected $result;
protected $params;
protected $executed = false;
protected $_queryCounter = 0;
public function __construct($dsn, $username = null, $password = null, $driver_options = null)
{
try
{
$this->connection = new PDO($dsn, $username, $password, $driver_options);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
$this->get_error($e);
}
}
public function query($sql, $params = array())
{
$this->result = $this->connection->prepare($sql);
$this->params = is_array($params) ? $params : array($params);
$this->executed = false;
}
public function bind($pos, $value, $type = null)
{
if ( is_null($type) )
{
switch (true)
{
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->result->bindValue($pos, $value, $type);
}
public function bindParam($pos, $value, $type = null)
{
if ( is_null($type) )
{
switch (true)
{
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->result->bindParam($pos, $value, $type);
}
public function execute($vars = array())
{
$this->_queryCounter++;
$this->executed = true;
foreach ( $vars as $k => $v )
{
$this->bind($k, $v);
}
return $this->result->execute();
}
public function fetch_array($vars = array())
{
if ( !$this->executed )
{
$this->execute($vars);
}
return $this->result->fetchAll(PDO::FETCH_ASSOC);
}
public function fetch_row($vars = array())
{
if ( !$this->executed )
{
$this->execute($vars);
}
return $this->result->fetch(PDO::FETCH_ASSOC);
}
public function lastInsertId()
{
return $this->connection->lastInsertId();
}
public function rowCount($vars = array())
{
if ( !$this->executed )
{
$this->execute($vars);
}
return $this->result->rowCount();
}
public function beginTransaction()
{
$this->connection->beginTransaction();
}
public function commit()
{
$this->connection->commit();
}
public function queryCounter()
{
return $this->_queryCounter;
}
public function debugDumpParams()
{
return $this->result->debugDumpParams();
}
public function get_error($e)
{
$this->connection = null;
die($e->getMessage());
}
public function getConnection()
{
return $this->connection;
}
public function __destruct()
{
$this->connection = null;
}
}

PDO::fetchRow does not exist. Assuming your $this->db object is a PDO instance, this doesn't work. PDO::query returns a PDOStatement result object. You need to fetch rows from it, not from the PDO object. If this doesn't help, you need to show what your database class is doing.

Related

unexpected 'A' Postman php api with JSON Response

Recently I try to create an API with PHP. all thing goes alright till suddenly I face unexpected 'a' error when trying to parse a JSON from the request throw Postman. I found something related to my issue but there is no solution in my case here : link
I send
{
"teacher_code":"sas"
}
JSON to teachers.php file to assign a student to the teacher
here is the teacher.php file content :
require_once ("classes/Rest.php");
require_once ("classes/api.php");
$api = new Api();
if($api->getHttpmethod() === 'POST'){
$api->validateParameter('teacher_code' ,$teacher_code = $api->getParam('teacher_code') , STRING , true);
$api->checkUserAccessablity();
$api->teacherCodeinRange($teacher_code);
$query = "INSERT INTO `group_users` (`user_id`,`group_id` )
VALUES (:user_id , (SELECT group_id FROM `groups` WHERE group_name = 'all' AND user_id =
(SELECT user_id FROM `teachers` WHERE t_code = :teacher_code)) )";
$keyValue = [
"user_id" => $api->getUserid() ,
"teacher_code" => $teacher_code
];
$result = $api->queryExecute($query , $keyValue );
$api->returnResponse(SUCCESS , SUCCESS_MESSAGE);
}
and api.php file :
require_once ("dbConnect.php");
require_once ("JWT.php");
class Api extends Rest
{
public $dbConn;
private $userId;
public function __construct()
{
parent::__construct();
$db = new dbConnect();
$this->dbConn = $db->connect();
}
public function setUserid($id){
$this->userId = $id;
}
public function getUserid(){
return $this->userId;
}
public function checkUserAccessablity(){
$payload = $this->deCodetoken();
$this->setUserid($payload->user_id);
$this->validateUser();
}
public function validateUser(){
$query = "SELECT * FROM `users` WHERE user_id = :id";
$keyValue = [
"id" => $this->getUserid()
];
$result = $this->queryExecute($query , $keyValue,true );
if(!$result){
$this->throwError(SYSTEM_ERROR , SYSTEM_ERROR_MESSAGE );
}
if(!is_array($result)){
$this->throwError(USER_NOT_FOUND_CODE , USER_NOT_FOUND_MESSAGE . $this->getUserid());
}
//TODO CHECK USER ACTIVE
return true;
}
public function teacherCodeinRange($tCode){
$query = "SELECT * FROM `teachers` INNER JOIN `licenses` ON (licenses.user_id = teachers.user_id)
WHERE teachers.t_code = :tcode LIMIT 1";
$keyValue = [
"tcode" => $tCode
];
$this->queryExecute($query , $keyValue,true );
return true;
}
public function teacherCodeinStudentrange($teacherID){
//TODO SELECT TEACHER STUDENT RANGE
$query = "SELECT DISTICT user_id FROM `teachers` INNER JOIN `groups` ON (groups.user_id = teachers.user_id)
INNER JOIN `group_users` ON (group_users.group_id = groups.group_id)
WHERE teachers.user_id = :teacherID AND groups.group_name = 'all' AND group_users.user_id = :userID ";
$keyValue = [
"userID" => $this->getUserid(),
"teacherID" => $teacherID,
];
$result = $this->queryExecute($query , $keyValue,true );
if(!is_array($result)){
$this->throwError(TEACHER_NOT_FOUND , TEACHER_NOT_FOUND_MESSAGE);
}
return true;
}
public function getHttpmethod(){
return $this->HttpMethod;
}
public function getParam($key){
return $this->arrayFinddeep($this->data , $key);
}
public function queryExecute($query , $keyArray , $isSelect = false){
$queryExec = $this->dbConn->prepare($query);
if(is_array($keyArray) || !empty($keyArray)) {
foreach ($keyArray as $key => &$value) {
$queryExec->bindParam(':' . $key, $value);
}
}
if($isSelect) {
$queryExec->execute();
$result = $queryExec->fetch(PDO::FETCH_ASSOC);
}else {
$result = $queryExec->execute();
}
return $result;
}
public function getLastuserId(){
return $this->dbConn->lastInsertId();
}
public function generateToken($payload , $secretKey){
try{
return \Firebase\JWT\JWT::encode($payload , $secretKey);
}catch (Exception $exception){
$this->throwError(JWT_PROCESSING_ERROR , $exception->getMessage());
}
}
public function deCodetoken(){
try{
$token = $this->getBearerToken();
$payload = \Firebase\JWT\JWT::decode($token , SECURITY_KEY , ['HS256']);
return $payload;
}catch (Exception $exception){
$this->throwError(ACCESS_TOKEN_ERROR , $exception->getMessage());
}
}
}
and the last class is Rest.php :
require_once ("Constans.php");
class Rest
{
protected $HttpMethod;
protected $request;
protected $data;
public function __construct(){
$this->HttpMethod = $_SERVER['REQUEST_METHOD'];
if($this->checkValidhttpMethod()) {
try{
$handler = fopen('php://input', 'r');
$this->request = stream_get_contents($handler);
}catch (Exception $exception){
//TODO HANDLE EXEPTION
}
$this->validateRequest();
}
}
public function checkValidhttpMethod(){
if(empty($this->HttpMethod) or !in_array($this->HttpMethod,ACCEPTABLE_HTTP_METHOD)){
$this->throwError(NOT_VALID_HTTP_METHOD,NOT_VALID_HTTP_METHOD_Message);
}
return true;
}
public function setJsonheader(){
header("content-type: application/json");
}
public function validateRequest(){
if($_SERVER['CONTENT_TYPE'] !== 'application/json'){
$this->throwError(REQUEST_CONTENT_NOT_VALID , REQUEST_CONTENT_NOT_VALID_MESSAGE);
}
try{
$this->data = json_decode($this->request , true);
}catch (Exception $exception){
//TODO HANDLE EXEPTION
}
}
public function processAPI(){
}
public function throwError($code , $message){
$this->setJsonheader();
echo json_encode(['error' => ['status' => $code , 'message' => $message]]);
exit;
}
public function returnResponse($code , $data){
$this->setJsonheader();
echo json_encode(['response' => ['status' => $code , 'result' => $data ]]);
exit;
}
//TODO SQL injection Validate
public function validateParameter($fieldName , $value , $dataType , $required = true){
if($required && empty($value)){
$this->throwError(PARAMETR_REQUIRED,PARAMETR_REQUIRED_MESSAGE . $fieldName);
}
//TODO SQL injection
//TODO CHECK The All Data Type
switch ($dataType){
case BOOLEAN :
if(!is_bool($value)){
$this->throwError(PARAMETR_DATA_TYPE_NOT_VALID , PARAMETR_DATA_TYPE_NOT_VALID_MESSAGE . $fieldName);
}
break;
case INTEGER :
if(!is_numeric($value)){
$this->throwError(PARAMETR_DATA_TYPE_NOT_VALID , PARAMETR_DATA_TYPE_NOT_VALID_MESSAGE . $fieldName);
}
break;
case STRING :
if(!is_string($value)){
$this->throwError(PARAMETR_DATA_TYPE_NOT_VALID , PARAMETR_DATA_TYPE_NOT_VALID_MESSAGE . $fieldName);
}
break;
case DONT_CARE :
break;
default:
break;
}
return $value;
}
public function arrayFinddeep($array, $search)
{
foreach($array as $key => $value) {
if (is_array($value)) {
$sub = $this->arrayFinddeep($value, $search);
if (count($sub)) {
return $sub;
}
} elseif ($key === $search) {
return $value;
}
}
return array();
}
/**
* Get hearder Authorization
* */
function getAuthorizationHeader(){
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER["Authorization"]);
}
else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
} elseif (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
// Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
//print_r($requestHeaders);
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
return $headers;
}
/**
* get access token from header
* */
function getBearerToken() {
$headers = $this->getAuthorizationHeader();
// HEADER: Get the access token from the header
if (!empty($headers)) {
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
return $matches[1];
}
}
$this->throwError(AUTHORIZATION_HEADER_NOT_FOUND , AUTHORIZATION_HEADER_NOT_FOUND_MESSAGE);
}
}
all queries go along queryExecute function in api.php class and recently I got that the bindParam function is not going to work fine too.
I really don't have any idea where the problem is, as In the reference said its somehow related to DB queries result. I try to use mysqli also but it did not work.
any help will be appreciated :-)

Updating MySQL tables throwing error

I never thought i would trip up on such an easy task, what i'm doing is getting rows from MySQL, and showing them on a form, the user can then update the values if needed:
<?php
include('includes/db_connection.php');
include('includes/sessions.php');
include('includes/functions.php');
include('includes/header.php');
include('includes/navbar-logged.php');
// AUTHENTICATION //
$row = DB::getInstance()->selectOneByField('membership', 'member_username', $member);
if ($row['member_user_class'] != 'Site Administrator') {
stderr("Sorry, <b>no authorization</b> to access this page.");
}
// AUTHENTICATION //
// CLOUD KEYS //
if (isset($_POST['submitCloudKeys']))
{
// TRY/CATCH //
try {
foreach ($_POST['cloudId'] as $val) {
DB::getInstance()->update(
'clouds',
'cloud_id',
$val,
[
'cloud_key' => $_POST['cloud_key'][$val]
]);
stdmsg('Cloud keys \'<b>'.$_POST['cloud_key'][$val].'</b>\' have been <b>updated</b>.');
}
} catch (Exception $e) {
stderr($e);
}
}
$rows = DB::getInstance()->select('SELECT * FROM `clouds`');
?>
<div class="panel panel-primary">
<div class="panel-heading">Current cloud hosts.</div>
<div class="panel-body">
<form action="clouds.php" method="post" class="form-horizontal container-fluid" role="form">
<?php $x = 0; ?>
<?php $z = 0; ?>
<?php foreach ($rows as $row) { ?>
<div class="row form-group">
<div class="col-sm-4 text-right"><label for="txtNetwork" class="control-label"><?php echo htmlspecialchars($row['cloud_name']) ?>:</div>
<div class="col-sm-8">
<input type="text" name="cloud_key[]" value="<?php echo htmlspecialchars($row['cloud_key']) ?>" size="30" class="form-control" />
<input type="hidden" name="cloudId[]" value="<?php echo $row['cloud_id']; ?>" />
</div>
</div>
<?php } ?>
<div class="row form-group">
<div class="col-sm-12 text-right">
<button type="submit" name="submitCloudKeys" class="btn btn-default">Update</button>
</div>
</div>
</form>
</div>
<div class="panel-footer">Update the <b>cloud hosts</b> keys.</div>
</div>
<?php
include('includes/footer.php');
I'm getting an error:
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'b447297ddb6be7377......................' in 'field list' in /home/admin/web/wraithpbns.com/public_html/includes/DB.php:268
Stack trace: #0 /home/admin/web/wraithpbns.com/public_html/includes/DB.php(268): PDOStatement->execute()
#1 /home/admin/web/wraithpbns.com/public_html/clouds.php(26): DB->update('clouds', 'cloud_id', '1', Array)
#2 {main}
The table names in MySQL are all correct, i don't see why i'm not able to update the form values, the "Unknown column" part is showing me the key value i'm trying to update, i have never had this issue before, any help would be appreciated guys!
UPDATED METHODS:
<?php
class DB
{
private static $instance;
public static function getInstance() {
if(is_null(self::$instance)) {
self::$instance = new DB();
}
return self::$instance;
}
public static function map(array $rows = array(), $keyColumn, $valueColumn = null) {
$result = array();
foreach($rows as $row) {
if(is_null($valueColumn)) {
$result[$row[$keyColumn]] = $row;
} else {
$result[$row[$keyColumn]] = $row[$valueColumn];
}
}
return $result;
}
private $pdo;
private function __construct() {
try {
$this->pdo = new PDO(
sprintf('%s:host=%s;dbname=%s',
DRIVER,
HOST,
DATA
),
USER,
PASS,
array(
PDO::ATTR_PERSISTENT => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8; SET CHARACTER SET utf8;'
)
);
} catch(Exception $ex) {
throw new Exception('Cannot connect to database.');
}
}
public function execute($query, array $params = []) {
$normParams = $this->normalizeParams($params);
$command = $this->pdo->prepare($query);
$command->closeCursor();
$status = $command->execute($normParams);
if(!$status) {
throw new Exception('DB::execute(): Can\'t execute query:');
}
return $status;
}
public function select($query, array $params = [], $fetchType = PDO::FETCH_ASSOC) {
$normParams = $this->normalizeParams($params);
$command = $this->pdo->prepare($query);
$command->closeCursor();
foreach($normParams as $paramName => $paramValue) {
if(is_array($paramValue)
&& isset($paramValue['type'])
&& isset($paramValue['value'])) {
$command->bindValue($paramName, $paramValue['value'], $paramValue['type']);
} else {
$command->bindValue($paramName, $paramValue);
}
}
if(!$command->execute()) {
throw new Exception('DB::select(): Can\'t execute query.');
}
return $command->fetchAll($fetchType);
}
public function selectValues($query, array $params = [], $fetchType = PDO::FETCH_ASSOC) {
$row = $this->selectOne($query, $params, $fetchType);
if(empty($row)) {
throw new Exception('DB::selectValues(): No values selected.');
} else {
return $row;
}
}
public function selectValue($query, array $params = []) {
$values = $this->selectValues($query, $params, PDO::FETCH_NUM);
return $values[0];
}
public function selectAll($tableName, $fetchType = PDO::FETCH_ASSOC) {
return $this->select(
sprintf('
SELECT *
FROM `%s`',
$tableName
),
[],
$fetchType
);
}
public function selectByField($tableName, $fieldName, $value, $fetchType = PDO::FETCH_ASSOC) {
return $this->select(
sprintf('
SELECT *
FROM `%s`
WHERE `%s` = :value',
$tableName,
$fieldName
),
[
':value' => $value
],
$fetchType
);
}
public function selectOne($query, array $params = [], $fetchType = PDO::FETCH_ASSOC) {
$rows = $this->select($query, $params, $fetchType);
return array_shift($rows);
}
public function selectOneByField($tableName, $fieldName, $value, $fetchType = PDO::FETCH_ASSOC) {
$rows = $this->selectByField($tableName, $fieldName, $value, $fetchType);
return array_shift($rows);
}
public function get($tableName, $fieldName, $value, $fetchType = PDO::FETCH_ASSOC) {
return $this->selectOneByField($tableName, $fieldName, $value, $fetchType);
}
public function insert($tableName, array $fields) {
$normParams = $this->normalizeParams($fields);
$paramNames = implode(', ', array_keys($normParams));
$fieldNames = '`' . implode('`, `', array_keys($fields)) . '`';
$command = $this->pdo->prepare(
sprintf('
INSERT INTO `%s` (%s)
VALUES (%s)',
$tableName,
$fieldNames,
$paramNames
)
);
$command->closeCursor();
if(!$command->execute($normParams)) {
throw new Exception('DB::insert(): Can\'t execute query.');
}
return $this->pdo->lastInsertId();
}
public function bulkInsert($tableName, array $rows = []) {
if(empty($rows)) {
return;
}
$fieldNames = array_keys($this->normalizeParams($rows[0]));
$normParams = [];
$paramNames = '';
$counter = 0;
foreach($rows as $row) {
$paramNames .= ((0 < $counter)? ',': '') . '(';
$nextParamNames = [];
foreach($row as $paramKey => $paramValue) {
$nextParamNames[] = ':' . $paramKey . $counter;
$normParams[':' . $paramKey . $counter] = $paramValue;
}
$paramNames .= implode(',', $nextParamNames);
$paramNames .= ')';
$counter++;
}
$command = $this->pdo->prepare(
sprintf('
INSERT INTO `%s` %s
VALUES %s',
$tableName,
$fieldNames,
$paramNames
)
);
$command->closeCursor();
if(!$command->execute($normParams)) {
throw new Exception('DB::bulkInsert(): Can\'t execute query.');
}
}
public function update($tableName, $fieldName, $fieldValue, array $updateFields, $updateAll = false) {
if(is_null($fieldName)) {
if(!$updateAll) {
throw new SystemException('Attempt to update all table records without confirmation.');
}
$sqlWhere = '';
} else {
$sqlWhere = sprintf('WHERE `%s` = %s', $fieldName, $fieldValue);
}
// echo $sqlWhere;
//
// exit;
$normUpdateFields = $this->normalizeParams($updateFields);
$sqlSetRows = [];
foreach($updateFields as $updateFieldName => $updateFieldValue) {
$sqlSetRows[] = sprintf('`%s` = %s', $updateFieldName, $updateFieldValue);
}
$sqlSet = implode(', ', $sqlSetRows);
$command = $this->pdo->prepare(
$sql = sprintf('
UPDATE `%s`
SET %s
%s',
$tableName,
$sqlSet,
$sqlWhere
)
);
$command->closeCursor();
foreach($normUpdateFields as $updateFieldName => $updateFieldValue) {
if(is_array($updateFieldValue)
&& isset($updateFieldValue['type'])
&& isset($updateFieldValue['value'])) {
$command->bindValue($updateFieldName, $updateFieldValue['value'], $updateFieldValue['type']);
} else {
$command->bindValue($updateFieldName, $updateFieldValue);
}
}
if(!empty($sqlWhere)) {
$command->bindValue(':' . $fieldName, $fieldValue);
}
if(!$command->execute()) {
throw new Exception('DB::update(): Can\'t execute query.');
}
}
public function remove($tableName, $fieldName = null, $value = null, $removeAll = false) {
$isExecuted = false;
if(is_null($fieldName)
&& is_null($value)
&& $removeAll) {
$isExecuted = $this->execute(sprintf('DELETE FROM `%s`', $tableName));
} else if(!is_null($fieldName)
&& !is_null($value)) {
$isExecuted = $this->execute(
sprintf('
DELETE FROM `%s`
WHERE `%s` = :value',
$tableName,
$fieldName
),
[
':value' => $value
]
);
}
if(!$isExecuted) {
throw new Exception('DB::remove(): Can\'t execute query.');
}
}
protected function normalizeParams(array $params = []) {
$normParams = [];
foreach($params as $paramKey => $paramValue) {
$normParams[(strlen($paramKey) && (':' === $paramKey{0}))? $paramKey: ':' . $paramKey] = $paramValue;
}
return $normParams;
}
/**
* Replaces any parameter placeholders in a query with the value of that
* parameter. Useful for debugging. Assumes anonymous parameters from
* $params are are in the same order as specified in $query
*
* #param string $query The sql query with parameter placeholders
* #param array $params The array of substitution parameters
* #return string The interpolated query
*/
public function interpolateQuery($query, $params) {
$keys = array();
# build a regular expression for each parameter
foreach ($params as $key => $value) {
if (is_string($key)) {
$keys[] = '/:'.$key.'/';
} else {
$keys[] = '/[?]/';
}
}
$query = preg_replace($keys, $params, $query, 1, $count);
#trigger_error('replaced '.$count.' keys');
return $query;
}
}
You have an logic issue within your update method ,
first , you are assigning a value then you are trying to bind a value,
$sqlWhere = sprintf('WHERE `%s` = %s', $fieldName, $fieldValue);
// ^^ ^^^^^^^^^^^^
and the same for your set clause :
$sqlSetRows[] = sprintf('`%s` = %s', $updateFieldName, $updateFieldValue);
// ^^ ^^^^^^^^^^^^^^^^^^
then as I told, you are trying to bind those values again using bindValue whether in your where clause :
$command->bindValue(':' . $fieldName, $fieldValue);
or in your this loop :
foreach($normUpdateFields as $updateFieldName => $updateFieldValue) {
....
$command->bindValue($updateFieldName, $updateFieldValue);
to solve you have two ways :
1 ) fix this by passing the write keys as follows :
$sqlWhere = sprintf('WHERE `%s` = :%s', $fieldName, $fieldName);
and for your set clause :
$sqlSetRows[] = sprintf('`%s` = :%s', $updateFieldName, $updateFieldName);
2 ) directly inject those values and leave your bindValue method which is not preferable:
$sqlSetRows[] = sprintf('`%s`="%s"', $updateFieldName, $updateFieldValue);
and $sqlWhere = sprintf('WHERE%s="%s"', $fieldName, $fieldValue);

mysqli_result could not be converted to string

Firstly,Thanks for reading this. How to solve my problems
CODE
$roomid = CMS::$MySql->Query("SELECT room_id FROM user_roomvisits WHERE user_id ='".$users['id']."' ORDER BY entry_timestamp DESC LIMIT 1");
$room = CMS::$MySql->Query("SELECT caption FROM rooms WHERE id ='".$roomid."'");
AND got the error :
Catchable fatal error: Object of class mysqli_result could not be converted to string.
Here mysql class
<?php
class MySql{
private $Link;
private $Statement;
public $Result = null;
private $FetchRows = Array();
public function __construct($Data)
{
$this->Link = new MySQLi($Data['mysql.hostname'], $Data['mysql.username'], $Data['mysql.password'], $Data['mysql.database']);
}
public function Query($Query)
{
if (isset($this->Statement))
{
$this->Statement->Close();
$this->Statement = null;
}
return $this->Link->query($Query);
}
public function Prepare($Query)
{
if (isset($this->Statement))
{
$this->Statement->Close();
}
$this->Statement = $this->Link->prepare($Query);
}
public function Execute($FuncArgs = null)
{
if (!is_array($FuncArgs))
{
$FuncArgs = func_get_args();
}
$Args = Array('');
foreach ($FuncArgs as &$Arg)
{
$Args[0] .= substr(gettype($Arg), 0, 1);
$Args[] =& $Arg;
}
call_user_func_array(Array($this->Statement, 'bind_param'), $Args);
if (!$this->Statement->Execute())
{
exit('Execute Stmt Error: '.$this->Statement->error);
}
return $this->Statement;
}
public function Fetch($Columns)
{
if (!is_array($Columns))
{
$Columns = func_get_args();
}
if ($this->Result == null)
{
$this->Result = array_combine($Columns, $Columns);
$Args = Array();
foreach ($Columns as $Column)
{
$Args[] =& $this->Result[$Column];
}
call_user_func_array(Array($this->Statement, 'bind_result'), $Args);
}
$RowsLeft = $this->Statement->fetch();
if (!$RowsLeft)
{
self::Clear();
return false;
}
return $this->Result;
}
?>
these are the mysql class for the PDO maybe?
$roomid = CMS::$MySql->Query("SELECT room_id FROM user_roomvisits WHERE user_id ='".$users['id']."' ORDER BY entry_timestamp DESC LIMIT 1");
while($row=mysql_fetch_array($roomid)){
$rumid=$row[0];
}
$room = CMS::$MySql->Query("SELECT caption FROM rooms WHERE id ='".$rumid."'");
the result from mysql query is object. u cannot echo objects
use var_dump() or print_r() to view the structure of them

PDO Merging Results in to One Array

I have a query result. Here is my code.
$P = new Product();
echo "<pre>";
print_r($P->get_product_image_path(1));
echo "</pre>";
In Product Class i have this function.
public function get_product_image_path($productid){
$sql = "SELECT picture FROM ".PREFIX."product_picture WHERE product_id = :id";
$this->query($sql);
$this->bind(':id', $productid);
if ($this->rowCount() > 0)
return $this->queryResults();
else
return NULL;
}
Here is my database class functions
public function query($sql)
{
return $this->_sql = $this->getPdo()->prepare($sql);
}
public function bind($param, $value, $type = null){
if (is_null($type)) {
switch (true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->_sql->bindValue($param, $value, $type);
}
public function execute(){
return $this->_sql->execute();
}
public function queryResults(){
$this->execute();
return $this->_sql->fetchAll(PDO::FETCH_ASSOC);
}
The result is returning
Array
(
[0] => Array
(
[picture] => 1328630682_1_xl.jpg
)
[1] => Array
(
[picture] => 1328630696_1_xl.jpg
)
[2] => Array
(
[picture] => 1328630689_1_xl.jpg
)
)
But i want to merge results like that
Array
(
[0] => 1328630682_1_xl.jpg
[1] => 1328630696_1_xl.jpg
[2] => 1328630689_1_xl.jpg
)
How can i do that. I'm new on PDO that's why i couldn't do it.
get rid of your database class.
do not extend your product class from database class.
use PDO to get an array in the desired form
here it goes
public function get_product_image_path($productid)
{
$sql = "SELECT picture FROM ".PREFIX."product_picture WHERE product_id = :id";
$stm = $this->pdo->prepare($sql);
$stm->execute(array($productid));
return $stm->fetchAll(PDO::FETCH_COLUMN, 0);
}
$pdo = new PDO(...);
$P = new Product($pdo);
echo "<pre>";
print_r($P->get_product_image_path(1));
echo "</pre>";
I wrote a new database class function
public function queryColumn($index = NULL){
$index = (isset($index)) ? intval($index) : 0;
$this->execute();
return $this->_sql->fetchAll(PDO::FETCH_COLUMN,$index);
}
And i edited my function
public function get_product_image_path($productid){
$sql = "SELECT picture FROM ".PREFIX."product_picture WHERE product_id = :id";
$this->query($sql);
$this->bind(':id', $productid);
if ($this->rowCount() > 0)
return $this->queryColumn();
else
return NULL;
}
Hence, i manage to merging arrays.

getting lastInsertId from PDO class

I'm using this class to connect to database. It works just fine, except I couldn't get the lastInsertId().
<?php
class connDB
{
public function connDB()
{
require_once( 'dbconfig/config.php' );
$this->confPDO = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_PERSISTENT => false,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"
);
try
{
$this->dbc = new PDO( "mysql:host=$this->dbHost;dbname=$this->dbName",
$this->dbUser, $this->dbPass, $this->confPDO );
}
catch( PDOException $errMsg )
{
return false;
}
}
public function exec( $sql, array $params = array() )
{
try
{
$this->stmt = $this->dbc->prepare( $sql );
if ( count( $params ) > 0 )
{
foreach ( $params as $k=>$v )
{
$this->bind($k, $v);
}
}
return $this->stmt->execute();
}
catch( PDOException $errMsg )
{
$this->dbc = null;
return false;
}
}
public function bind( $param, $value, $type = null )
{
if ( is_null( $type ) )
{
switch ( true )
{
// Boolen parameter
case is_bool( $value ):
$type = PDO::PARAM_BOOL;
break;
// Integer parameter
case is_int( $value ):
$type = PDO::PARAM_INT;
break;
// Null parameter
case is_null( $value ):
$type = PDO::PARAM_NULL;
break;
// String parameter
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue( $param, $value, $type );
}
public function single()
{
return $this->stmt->fetch(PDO::FETCH_ASSOC);
}
public function resultset()
{
return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function rowCount()
{
return $this->stmt->rowCount();
}
}
Usage: [SELECT]
$sql = "SELECT * FROM < table >";
$db->exec($sql, $params);
$rows = $db->resultset();
foreach ($rows as $row)
{
echo $row['< column >'] . "\n";
}
Usage: [INSERT]
$sql = "INSERT INTO < table > (< column_1 >, < column_2 >, ... ) VALUES
(:valuename_1,
:valuename_2, ...)";
$params = array(':valuename_1' => 'value', ':valuename_2' => 'value', ...);
$db->exec($sql, $params);
I tried to do it this way:
include_once'classe.php';
$db = new connDB();
$sql = "INSERT INTO < table > (< column_1 >, < column_2 >, ... ) VALUES
(:valuename_1,
:valuename_2, ...)";
$params = array(':valuename_1' => 'value', ':valuename_2' => 'value', ...);
$db->exec($sql, $params);
$id = $db->lastInsertId();
I am getting an error:
Fatal error: Call to undefined method connDB::lastInsertId() in
I've tried adding a method into the class:
public function lastinsert()
{
// Return result
return $this->stmt->lastInsertId();
}
Then I called it like this this:
$db = new connDB();
$id = $db->lastinsert();
The error this time was
Fatal error: Call to undefined method PDOStatement::lastInsertId() in
There is no lastInsertId() method in your class.
You need to add it to the connDB class.
you need to call $dbc, not $stmt to get lastInsertId();
$this->dbc->lastInsertId();
as this function belongs to PDO class, not PDO statement class
Also, this piece of code may cause the problem
catch( PDOException $errMsg )
{
$this->dbc = null;
return false;
}
}
Make your exec() function this way
public function exec( $sql, array $params = array() )
{
$this->stmt = $this->dbc->prepare( $sql );
foreach ( $params as $k=>$v )
{
$this->bind($k, $v);
}
return $this->stmt->execute();
}
Using the same database class and was able to use lastInsertId like this:
$db = new connDB();
...
$_SESSION['users_id'] = $db->dbc->lastInsertId('id');
If you are using the model's save function:
$row->save();
You can use:
return $row->save();
which returns the id

Categories