PDO Binding Sequence/MySQL Incompatibility? - php

I'm using MySQL(i)-community-5.3 if not mistaken. After finally getting the hang of PDO, I can now conclude that the infected sectore is that which processes binding, all other functions are fine (that I know of). Below I will present a function which works and also doesn't work (the sequence without anything to do with binding works flawlessly.
Function you() is as followes:
public function you($row) {
if(isset($_COOKIE["SK"])) {
$usr = $this->baseXencode($_SESSION["username"]);
$q = "SELECT $row FROM SN_users WHERE username=:USR";
$this->netCore->q($q);
$this->netCore->bind(":USR", $usr);
$result = $this->netCore->single();
$result = $result[$row];
} else {
$q = "SELECT $row FROM SN_users WHERE username='".$this->baseXencode("Anonymous")."' AND password='".$this->baseXencode("Anonymous")."'";
$result = $this->netCore->q($q);
$result = $this->netCore->single();
$result = $result[$row];
}
return $result;
}
}
(As you can see, when pre-allocating the username/password combo for Anonymous users, the function executes perfectly whereas binding within the if() section does not, returning the value 1.
Below is my binding function bind() (if you may require any other code, I will edit this post further~^^):
EDIT:
Below is the netCore class:
class netCore {
private $boot;
private $dbHost = "";
private $dbNAME = "";
private $dbPASS = "";
private $dbUSR = "";
private $err;
private $state;
public function __construct() {
$bootloadr = "mysql:host=".$this->dbHost.";dbname=".$this->dbNAME.";charset=UTF8";
$opt = array(PDO::ATTR_PERSISTENT => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
try {
$this->boot = new PDO($bootloadr, $this->dbUSR, $this->dbPASS, $opt);
} catch(PDOException $e) {
$this->err = "<b>Lebensborn® netCore™ Error:</b> An exception has been raised during Network-to-Database procedures.<br /><b>Message:</b> ".$e->getMessage().".";
}
}
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->state->bindParam($param, $value, $type);
}
public function debug() {
return $this->state->debugDumpParams();
}
public function exe() {
return $this->state->execute();
}
public function count() {
$this->exe();
return $this->state->fetchColumn();
}
public function q($q) {
$this->state = $this->boot->prepare($q);
}
public function set() {
$this->exe();
return $this->state->fetchAll(PDO::FETCH_ASSOC);
}
public function single() {
$this->exe();
return $this->state->fetch(PDO::FETCH_ASSOC);
}
public function transBegin() {
return $this->boot->beginTransaction();
}
public function transCancel() {
return $this->boot->rollBack();
}
public function transEnd() {
return $this->boot->commit();
}
}

Related

How to return sepcyfic type function in PHP?

I'm trying to change the old code. I have two classes. One is responsible for validating the field and the other adds the value to the database if the field has passed validation.
I want each function to return a specific type. But when, for example, I assigned: string to the validateschool function, the program does not work. Someone might say why.
class SchoolUpdating
{
private $database;
private $data;
private $schoolValidation;
public function __construct($database, $data, $schoolValidation)
{
$this->database = $database;
$this->data = $data;
$this->schoolValidation = $schoolValidation;
}
public function UpdateSchool(): string
{
if(empty($this->schoolValidation->getError())) {
$school = htmlspecialchars($this->data["school"]);
$session = htmlspecialchars($_SESSION['user_id']);
$query = $this->database->ConnectDatabase()->prepare("UPDATE user set school = :school where user_id = :id");
$query->bindParam(':school', $school, PDO::PARAM_STR);
$query->bindParam(':id', $session, PDO::PARAM_INT);
$query->execute();
}
}
}
class SchoolValidation
{
private string $data;
private $database;
private string $error = '';
public function __construct($database, $data)
{
$this->database = $database;
$this->data = $data;
}
public function getError(): string
{
return $this->error;
}
public function ValidateSchool(): string
{
$val = htmlspecialchars($this->data['school']);
if(empty($val))
{
return $this->error = "Podaj szkole";
}else if(!preg_match('/^[A-Za-z_\-\s]+$/', $val))
{
return $this->error = "Nieporawny format";
}
}
}

PHP OOP binding problem inside the method

I try so hard to create this method with prepare, bind, and execute inside the class. But I guess I don't have enough knowledge about it whatever I do I couldn't make it work. I'm looking google for hours. I know that below code is wrong about binding but Can someone show me the correct way to do binding inside this method?
class User {
protected static $db_table = "users";
protected static $db_table_fields = array('username', 'password', 'first_name', 'last_name');
public $id;
public $username;
public $password;
public $first_name;
public $last_name;
protected function properties() {
$properties = array();
foreach (static::$db_table_fields as $db_field) {
if (property_exists($this, $db_field)) {
$properties[$db_field] = $this->$db_field;
}
}
return $properties;
}
protected function clean_properties() {
global $database;
$clean_properties = array();
foreach ($this->properties() as $key => $value) {
$clean_properties[$key] = $value;
}
return $clean_properties;
}
public function create($params= []){
global $database;
$properties = $this->clean_properties();
$fields = ":" . implode("',:'", static::$db_table_fields);
$sql= "INSERT INTO " .static::$db_table . "(" . implode(",", array_keys($properties)) . ")
VALUES('". $fields ."')";
$stmt = $database->prepare($sql);
foreach ($fields as $field => &$params) {
$stmt->bindValue($field, $params);
}
if ($stmt->execute()) {
$this->id = $database->InsertId();
return true;
} else {
return false;
}
}
So I made my code like this for binding. I don't know if it is the correct way. I know I keep changing stuff. I guess it is the best way to learn to try different stuff.
//$param = array('x'=>$x, 'y'=>$y);
public function bind($param = [], $type=NULL){
foreach($param as $key=>&$value){
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->stmt->bindValue(':'.$key,$value);
}
return $this->stmt;
}

Can't retrieve data in PHP API

I'm building a simple CRUD app as a learning exercise in Angularjs and PHP. I have a shell page, mysql backend, a PHP API that handles the SQL requests, and I'm using Angularjs to handle the flow of data between the shell page and the API. I'm working off an API modeled here:
http://angularcode.com/demo-of-a-simple-crud-restful-php-service-used-with-angularjs-and-mysql/
I've tested every component of this app so far and everything works cleanly except the API. All I've done to modify the original was change the syntax to PDO and I adjusted the response function because the existing one didn't work.
The abstract class:
<?php
class REST {
public $_allow = array();
public $_content_type = "application/json";
public $_request = array();
private $_method = "";
private $_code = 200;
public function __construct(){
$this->inputs();
}
public function get_referer(){
return $_SERVER['HTTP_REFERER'];
}
/*public function response($data,$status){
$this->_code = ($status)?$status:200;
$this->set_headers();
echo $data;
exit;
}*/
public function response($status, $status_message, $data){
header("HTTP/1.1 $status $status_message");
$response['status'] = $status;
$response['status_message'] = $status_message;
$response['data'] = $data;
$json_response = json_encode($response);
}
private function get_status_message(){
$status = array(
200 => 'OK',
201 => 'Created',
204 => 'No Content',
404 => 'Not Found',
406 => 'Not Acceptable');
return ($status[$this->_code])?$status[$this->_code]:$status[500];
}
public function get_request_method(){
return $_SERVER['REQUEST_METHOD'];
}
private function inputs(){
switch($this->get_request_method()){
case "POST":
$this->_request = $this->cleanInputs($_POST);
break;
case "GET":
case "DELETE":
$this->_request = $this->cleanInputs($_GET);
break;
case "PUT":
parse_str(file_get_contents("php://input"),$this->_request);
$this->_request = $this->cleanInputs($this->_request);
break;
default:
$this->response('',406);
break;
}
}
private function cleanInputs($data){
$clean_input = array();
if(is_array($data)){
foreach($data as $k => $v){
$clean_input[$k] = $this->cleanInputs($v);
}
}else{
if(get_magic_quotes_gpc()){
$data = trim(stripslashes($data));
}
$data = strip_tags($data);
$clean_input = trim($data);
}
return $clean_input;
}
private function set_headers(){
header("HTTP/1.1 ".$this->_code." ".$this->get_status_message());
header("Content-Type:".$this->_content_type);
}
}
?>
And the API itself:
<?php
require_once("Rest.inc.php");
class API extends REST {
public $data = "";
private $db = NULL;
private $conn = NULL;
public function __construct(){
parent::__construct();
$this->dbConnect();
}
/*
* Connect to Database
*/
private function dbConnect(){
$this->conn = null;
$servername="myServer";
$dbname="mySQL";
$username="myUN";
$password="myPW";
try{
$this->conn = new PDO("mysql:host=$servername;Database=$dbname",$username, $password);
}catch(PDOException $e){
echo "Failed:" . $e->getMessage();
}
return $this->conn;
}
/*
* Dynmically call the method based on the query string
*/
public function processApi(){
//$func = strtolower(trim(str_replace("/","",$_REQUEST['x']))); //<<--NEED TO FIX THIS. x determines which function to call
$func = 'quote';
if((int)method_exists($this,$func) > 0){
$this->$func();
}else{
$this->response(404,'','');
}
}
private function quote(){
if($this->get_request_method() != "GET"){
$this->response(406, '', '');
}
$id = (int)$this->_request['id'];
if($id > 0){
try{
$sql = "SELECT * FROM mysql.Quotes WHERE ID =:ID";
$query = $this->conn->prepare($sql);
$query->bindParam(":ID", $id);
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
}catch(PDOException $e){
echo "Failed:" . $e->getMessage();
}
echo $this->response(200,"Success",$result);
}
}
// Initiate Library
$api = new API;
$api->processApi();
?>
One issue I'm aware of is that the commented portion in processAPI() does not work. It's supposed to grab the initial part of the URL and determine which function to run based on based on that, but my server keeps throwing an error. My workaround for the time being is just to hard-code $func = 'quote';
More importantly, though, the API returns an empty object whenever it runs. It connects to the DB and executes without errors, and it does return an object as designed -- there just isn't anything inside it. If I pull out the core components -- the DB connection, the SQL request, and the response function -- and run them on their own, they correctly pull the data and pass it on to the shell. So something in the REST class or the API must be fouling it up, but I'm not handy enough in PHP yet to figure out where it's going wrong. I'd appreciate any feedback.

How to retrieve values from another class initialization without function to return them manually

I'm not sure how to go about this.
I have two classes, LairEngine and RespondEngine.
RespondEngine has certain methods in it that require values that are inside an initialization of LairEngine.
How do I make an initialization of RespondEngine automatically grab those values other than having to write methods inside class LairEngine to return values and then pass those as arguments to RespondEngine.
I'm trying to build a framework for telegram bots.
index.php
require_once('init_lairfw.php');
//Load up LairEngine and RespondEngine
$engine = new LairEngine;
$respond = new RespondEngine;
$respond->sendText("HEY");
init_lairfw.php
spl_autoload_register(null, false);
spl_autoload_extensions('.mod.php, .lair.php');
function ModuleLoader($class) {
if(file_exists(strtolower('modules/'.$class.'.mod.php'))) {
include(strtolower('modules/'.$class.'.mod.php'));
}
}
function EngineLoader($class) {
if(file_exists(strtolower('engine/'.$class.'.lair.php'))) {
include(strtolower('engine/'.$class.'.lair.php'));
}
}
spl_autoload_register('ModuleLoader');
spl_autoload_register('EngineLoader');
engine/lairengine.php
class LairEngine {
private $config;
private $url;
private $data;
private $datatypes;
//The construct method is executed, and requrired information(incoming data, outgoing data)
//is processed and allocated for further use
function __construct()
{
$this->config = json_decode(file_get_contents('config/.Engine'), true);
$this->url = array(
"https://api.telegram.org/bot".$this->config['token'],
"https://api.telegram.org/bot".$this->config['token']."/getFile?file_id=",
"https://api.telegram.org/file/bot".$this->config['token']."/"
);
$this->data = file_get_contents("php://input");
$this->data = json_decode($this->data, TRUE);
$this->process();
}
//Process the message and find out what kind of message it is
private function process()
{
$k = array_keys($this->data['message']);
switch($k[4])
{
case('reply_to_message'):
$f=5; $this->dataTypes = array('msg_type' => 'reply');
$this->dataTypes['reply_to_content'] = array_keys($this->data['message']['reply_to_message'][4]);
break;
case('new_chat_title'):
$f=4; $this->dataTypes = array('msg_type' => 'group_name_change');
break;
case('new_chat_photo'):
$f=4; $this->dataTypes = array('msg_type' => 'group_pic_change');
break;
case('forward_from'):
$f=6; $this->dataTypes = array('msg_type' => 'forward');
break;
case('new_chat_participant'):
$f=null; $this->dataTypes = array('msg_type' => 'new_user');
break;
case('left_chat_participant'):
$f=null; $this->dataTypes = array('msg_type' => 'user_leave');
break;
default:
$f=4; $this->dataTypes = array('msg_type' => 'original');
}
$this->dataTypes['msg_content'] = ($f!==null) ? $k[$f] : null;
}
public function returnData()
{
$this->data['lair_return'] = $this->dataTypes;
return $this->data;
}
public function returnDataTypes()
{
return $this->datatypes;
}
public function returnURL()
{
return $this->url;
}
public function returnchatdata()
{
return self::$data['message']['chat'];
}
public function throwError($e,$t)
{
switch($t)
{
case(0): trigger_error($e, E_USER_NOTICE); break;
case(1): trigger_error($e, E_USER_WARNING); break;
case(2): trigger_error($e, E_USER_ERROR); break;
}
}
}
engine/respondengine.php
class RespondEngine {
public function sendText($response,$chatID=null,$url=null)
{
if(!$chatID)
{
//need the value from initalization of LairEngine
}
if(!$url)
{
//need the value from initalization of LairEngine
}
$request = $url."sendMessage?chat_id=".$chatID."&text=".urlencode($response);
print_r($request);
if(file_get_contents($request)) { return true; } else { return false; }
}
}

PHP - MySQL wrapper class advice

i am writing a MySQL wrapper class to:
a.) replace a current one
b.) make life easier in terms of custom functionality
c.) to learn and improve
I am looking on advice on how to improve my techniques and coding style, so i would appreciate any input you could provide.
DISCLAIMER:
I am aware there are other database abstraction methods such as PDO but i wanted to write my own for the above reasons
Thanks,
Lee
Test Call
#!/usr/bin/php
<?php
include('mysql.class.php');
$_mysql = new mysqli_ls( array( 'debug_log' => TRUE, 'query_log' => TRUE ) );
if ($_mysql->connect('host','user','password','db') === FALSE) print_r( $_mysql->get_error() );
else print "#1 connected\n";
if ($_mysql->set_database('auth_tracker_test') === FALSE) print_r( $_mysql->get_error() );
else print "#1 database changed\n";
/// Execute standard query
$sql = "SELECT * from user";
if ($_mysql->SQLQuery($sql) === TRUE) print "#1 SELECT Query worked\n";
else print print_r( $_mysql->get_error() );
#print_r($_mysql->getArray());
print_r($_mysql->getRow());
$_mysql->disconnect();
?>
<?php
class mysqli_ls
{
/**************************************************************************/
/* SETUP VARIABLES */
/**************************************************************************/
private $E_OK = TRUE;
private $E_ERROR = FALSE;
private $db_host;
private $db_user;
private $db_port;
private $db_name;
private $db_pass;
private $result;
private $link = FALSE;
private $errorArr = array();
private $config = array( // Location of exisiting
'config_load' => FALSE,
'config_path' => 'database.cfg.php',
// Record errors to a file
'debug_log' => FALSE,
'debug_log_path' => '/tmp/mysql.debug.log',
// Record queries to a file
'query_log' => FALSE,
'query_log_path' => '/tmp/mysql.debug.log' );
private $fh_debug = FALSE;
private $fh_query = FALSE;
private $fh_config = FALSE;
/**************************************************************************/
/* MAGIC FUNCTIONS */
/**************************************************************************/
public function __construct( $config = '' )
{
// Config vars
if ( !empty($config) && is_array($config) ) $this->set_config($config);
// Open file handles if logs are required
// Debug Log
if ($this->config['debug_log'] === TRUE)
{
if (! $this->fh_debug = fopen($this->config['debug_log_path'], 'a') )
{
$this->handle_error('#01A', 'could not open debug log');
return $this->E_ERROR;
}
}
// Query Log
if ($this->config['query_log'] === TRUE)
{
if (! $this->fh_query = fopen($this->config['query_log_path'], 'a') )
{
$this->handle_error('#01B', 'could not open query log');
return $this->E_ERROR;
}
}
// Check mysqli functions are available
if (!function_exists('mysqli_connect'))
{
$this->handle_error('#01C', 'mysqli not installed');
return $this->E_ERROR;
}
return $this->E_OK;
}
public function __deconstruct()
{
if ($this->link) $this->disconnect();
return $this->E_OK;
}
/**************************************************************************/
/* CONNECTION MANAGEMENT */
/**************************************************************************/
public function connect($db_host='', $db_user='', $db_pass='', $db_name, $db_port='3306')
{
if (empty($db_host) || empty($db_user) || empty($db_pass) || empty($db_name) || empty($db_port))
{
$this->handle_error('#02A', 'Missing connection variables');
return $this->E_ERROR;
}
$this->db_host = $db_host;
$this->db_user = $db_user;
$this->db_pass = $db_pass;
$this->db_name = $db_name;
$this->db_port = $db_port;
$this->link = #new mysqli($this->db_host, $this->db_user, $this->db_pass, $this->db_name, $this->db_port);
if (mysqli_connect_error($this->link))
{
$this->handle_error(mysqli_connect_errno($this->link), mysqli_connect_error($this->link));
return $this->E_ERROR;
}
return $this->E_OK;
}
public function disconnect()
{
if ($this->link)
{
if ($this->link->close() === TRUE) return $this->E_OK;
else
{
$this->handle_error($this->link->errno, $this->link->error);
return $this->E_ERROR;
}
}
$this->handle_error('#03A','no activate database connection');
return $this->E_ERROR;
}
public function connect_existing()
{
}
public function set_database($database)
{
if ( $this->link->select_db($database) === FALSE )
{
$this->handle_error($this->link->errno, $this->link->error);
return $this->E_ERROR;
}
$this->E_OK;
}
/**************************************************************************/
/* SQL INTERFACE */
/**************************************************************************/
public function insert()
{
}
public function update()
{
}
public function delete()
{
}
public function select()
{
}
public function query($sql)
{
// If the result set has cleaned up, do so before a new query
if ($this->result) $this->result->close();
// Record query
if ($this->config['query_log'] === TRUE) $this->write_log('query', $sql);
if ($result = $this->link->query($sql));
{
$this->result = $result;
return $this->E_OK;
}
// Clean up the result set
$result->close();
// Query failed, handle error
$this->handle_error($this->link->errno, $this->link->error);
return $this->E_ERROR;
}
/**************************************************************************/
/* RESULT FUNCTIONS */
/**************************************************************************/
public function getArray($type = 'assoc')
{
switch($type)
{
case 'num':
$type = MYSQLI_NUM;
break;
case 'assoc':
$type = MYSQLI_ASSOC;
break;
case 'both':
$type = MYSQLI_BOTH;
break;
default:
$this->handle_error('#12A','invalid field type. Options are include num, assoc, both');
return $this->E_ERROR;
break;
}
$resultArr = array();
while( $row = $this->result->fetch_array( $type ) )
{
$resultArr[] = $row;
}
return $resultArr;
}
public function getRow($type = 'assoc')
{
switch($type)
{
case 'num':
$type = MYSQLI_NUM;
break;
case 'assoc':
$type = MYSQLI_ASSOC;
break;
case 'both':
$type = MYSQLI_BOTH;
break;
default:
$this->handle_error('#13A','invalid field type. Options are include num, assoc, both');
return $this->E_ERROR;
break;
}
return $this->result->fetch_array( $type );
}
public function num_row()
{
return $this->result->num_rows;
}
public function insert_id()
{
return $this->link->insert_id;
}
public function affected_rows()
{
return $this->link->affected_rows;
}
/**************************************************************************/
/* LEGACY SUPPORT */
/**************************************************************************/
public function SQLQuery($sql='')
{
if (empty($sql))
{
$this->handle_error('#19A','missing query string');
return $this->E_ERROR;
}
// Check for a select statement
if ( preg_match("/^select/i",$sql) === 0)
{
$this->handle_error('#19A','incorrect query type, SELECT expected');
return $this->E_ERROR;
}
// Execute query
if ($this->query($sql) === $this->E_ERROR) return $this->E_ERROR;
// Return number of rows
return $this->num_row();
}
public function SQLModify($sql='')
{
if (empty($sql))
{
$this->handle_error('#19A','missing query string');
return $this->E_ERROR;
}
// Execute query
if ($this->query($sql) === $this->E_ERROR) return $this->E_ERROR;
// Return affected rows
$this->affected_rows();
}
public function numRow()
{
return $this->num_row();
}
/**************************************************************************/
/* LOGGING AND DEBUGGING */
/**************************************************************************/
private function write_log($type, $msg)
{
$msg = date('Y-m-d H:i:s') ."\t". $type ."\t". $msg ."\n";
switch($type)
{
case 'error':
fwrite($this->fh_debug, $msg);
break;
case 'query':
fwrite($this->fh_query, $msg);
break;
default:
return $this->E_ERROR;
break;
}
}
private function handle_error($errormsg, $errorno)
{
$this->errorArr[] = array( 'code' => $errorno,
'error' => $errormsg );
if ($this->config['debug_log'] === TRUE)
{
$msg = "($errorno) $errormsg";
$this->write_log('error', $msg);
}
return $this->E_OK;
}
public function get_error($type = 'string')
{
switch($string)
{
case 'string':
$error = end($this->errorArr);
return $error['error'] .' ('. $error['code'] .')';
break;
case 'array':
return end($this->errorArr);
break;
}
return false;
}
/**************************************************************************/
/* SET CONFIG VARS */
/**************************************************************************/
public function set_config($config)
{
foreach ($config as $key => &$value)
{
if ( ! isset($this->config[$key]) )
{
$this->handle_error('#19A','invalid field type');
return $this->E_ERROR;
}
$this->config[$key] = $value;
}
return $this->E_OK;
}
/**************************************************************************/
} // Class END
?>
I made one myself once and added another class named MySqlTable, which represented a table. I returned it in the __GET function, so you could call a table with
$sql->tablename->select();
Here's the code for the __get function:
function __GET($name)
{
return new MySqlTable($this, $name);
}
The class was like this:
class MySqlTable
{
private $table;
private $mySql;
function MySqlTable(&$oMySql, $sTable)
{
$this->mySql = $oMySql;
$this->table = $sTable;
}
function &select($sWhere = '')
{
if (empty($sWhere))
{
$data = $this->mySql->query("SELECT * FROM " . $this->table);
}
else
{
$data = $this->mySql->query("SELECT * FROM " . $this->table . " WHERE " . $sWhere);
}
return $this->mySql->resultToArray($data);
}
}
Currently, your mysqli_ls class contains the result of a query. This makes it impossible to do two queries and use the results of the first query after the second query ran.
A better way would be to let the SQLQuery() method return a result object, which contains the result handle and methods to retrieve rows from the result.

Categories