Having issue with oop and pdo in php - php

I have a form on a website. This form collects data about an EVENT. The event has 20 fields besides the ID that are in the table that corresponds to the event.
Before I was just taking the ($_POST['submit']) and if true, inserting the event fields into the database using mysql_query.
Now I'm trying to use oop and this pdo and I've pretty much defeated myself at this point. I am sure I'm doing lots of things wrong.
<?php
$str = $_SERVER['DOCUMENT_ROOT'];
include $str."/wp-config.php";
$config['db'] = array(
'host' => DB_HOST,
'username' => DB_USER,
'password' => DB_PASSWORD,
'dbname' => DB_NAME,
'charset' => DB_CHARSET
);
$db = new PDO('mysql:host='.$config['db']['host'].';dbname='.$config['db']['dbname'].';charset='.$config['db']['charset'], $config['db']['username'], $config['db']['password']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDF::ATTR_EMULATE_PREPARES, false);
class match extends event {
public $_matchno;
public $_completed;
function __construct() {
$this->_completed = "N";
}
public function addMatch($matchno) {
$sql = $db->prepare("INSERT INTO wp_hue5gf_match_details (matchno, event_name, dateofmatch, fighttype, comp, matchref, fightclass)
VALUES (".$matchno.", $this->_eventname, $this->_doe, $this->_status, $this->_completed, $this->_refree, $this->_fightclass)");
$sql->execute();
}
}
class event {
public $_promouser;
public $_eventname;
public $_fightclass;
public $_no_of_matches;
public $_status;
public $_doe;
public $_venue;
public $_city;
public $_state;
public $_zip;
public $_sanc_body;
public $_doctor;
public $_refree;
public $_referee2;
public $_judge;
public $_judge2;
public $_judge3;
public $_boxcomm;
public $_descript;
function __construct() {
$this->_promouser = $_SESSION['username'];
$this->_eventname = $_POST['ename'];
$this->_fightclass = $_POST['efightclass'];
$this->_no_of_matches = $_POST['no_of_matches'];
$this->_status = $_POST['estatus'];
$this->_doe = $_POST['year']."-".$_POST['month']."-".$_POST['day'];
$this->_venue = $_POST['venue'];
$this->_city = $_POST['city'];
$this->_state = $_POST['state'];
$this->_country = $_POST['country'];
$this->_zip = $_POST['zip'];
$this->_sanc_body = $_POST['sbody'];
$this->_doctor = $_POST['doctor'];
$this->_refree = $_POST['refree'];
$this->_referee2 = $_POST['refree2'];
$this->_judge = $_POST['judge'];
$this->_judge2 = $_POST['judge2'];
$this->_judge3 = $_POST['judge3'];
$this->_boxcomm = $_POST['boxcom'];
$this->_descript = $_POST['descript'];
}
public function insertEvent() {
$sql = $db->prepare("INSERT INTO event (promouser, eventname, fightclass, no_of_matches, status, doe, venue, city, state, country, zip,
sanc_body, doctor, refree, referee2, judge, judge2, judge3, boxcomm, descript) VALUES ($this->_promouser, $this->_eventname, $this->_fightclass, $this->_no_of_matches, $this->_status, $this->_venue,
$this->_city, $this->_state, $this->_country, $this->_zip, $this->_sanc_body, $this->_doctor, $this->_refree, $this->_referee2, $this->_judge, $this->_judge2, $this->_judge3, $this->_boxcomm, $this->_descript)");
$sql->execute();
}
}
?>
So that is my class page. Now to the add event page. I am clearly doing something way wrong. And I have no idea where to start.
<?php
require_once(bloginfo( 'template_url' ).'/definedClasses.php');
if($_POST['submit'])
{
$event = new event();
event::insertEvent();
for($y=1;$y<= $event->_no_of_matches;$y++)
{
$match = new match();
match::addMatch($y);
}
}
?>
<form name="addevent" method="post" action="" enctype="multipart/form-data" >
<!-- The form here with all these inputs for the post values -->
</form>
I'm sure I'm trying to do too much at once. I should probably trim this down to a much smaller problem then work through it. But I have no clue where to start. I'm not looking for you to do this for me, I am looking for some guidance on what I don't understand and. I'm pretty sure it has something to do with the PDO. if this was mysql_ like it used to be I have a feeling that I would have it running right.
Thanks for taking a peek.

You can't use $db in your classes because they don't know it exists.
What is dependency injection?
Pass the PDO object as a parameter in your constructor
function __construct( PDO $db ) {
$this->$db = $db;
}
Then use $this->db instead of $db
Also use $event->insertEvent() instead of using it statically.
A better approach would be
$event = new Event( $_POST );
$eventSaver = new EvenSaver( $db ); //Name is stupid but you get it
$eventSaver->saveEvent( $event );
but that's for a different time.

Related

How To Get Values Out of An Array Inside Of A Class

I have a form that is passing array values to create_parts.php, then I am trying to pass those values to the parts class to insert into the database. At this point I am just lost... The form passes to create_parts.php, I can echo the results of the of the array. However in my class I cant get any values thus, my insert into the database is just a bunch of NULL.
<?php
include_once '../config/database.php';
include_once '../objects/parts_object.php';
$database = new Database();
$db = $database->getConnection();
$parts= new parts($db);
$parts->est_part_idArr=$_POST['est_part_id'];
$parts->part_qtyArr=$_POST['part_qty'];
$parts->part_numArr=$_POST['part_num'];
$parts->part_discArr=$_POST['part_disc'];
$parts->part_costArr=$_POST['part_cost'];
$parts->create();
I am able to to echo out the results here and get
{"est_part_idArr":["123","124"],"part_qtyArr":["4","6"],"part_numArr":
["2334","3344"],"part_discArr":["part","parts"],"part_costArr":["56","33"]
and echo the $stmt
{"queryString":"INSERT INTO \r\n partsT\r\n SET \r\n est_part_id=:est_part_id, part_qty=:part_qty, part_num=:part_num, part_disc=:part_disc, part_cost=:part_cost"}
However in part_object.php I cant get anything to work. I can it to insert to the database but it is all NULL.
class parts{
private $conn;
private $table_name = "partsT";
public $est_part_idArr;
public $part_qtyArr;
public $part_numArr;
public $part_discArr;
public $part_costArr;
public function __construct($db){
$this->conn = $db; }
function create(){
$query = "INSERT INTO
" . $this->table_name . "
SET
est_part_id=:est_part_id, part_qty=:part_qty, part_num=:part_num, part_disc=:part_disc, part_cost=:part_cost";
$stmt = $this->conn->prepare($query);
if(!empty($this->$est_part_idArr)){
for ($i = 0; $i < count($this->$est_part_idArr); $i++) {
if(!empty($this->$est_part_idArr[$i])){
$est_part_id = $this->$est_part_idArr[$i];
$part_qty = $this->$part_qtyArr[$i];
$part_num = $this->$part_numArr[$i];
$part_disc = $this->$part_discArr[$i];
$part_cost = $this->$part_costArr[$i];
$stmt->execute(array(
':est_part_id' => $est_part_id,
':part_qty' => $part_qty,
':part_num' => $part_num,
':part_disc' => $part_disc,
':part_cost' => $part_cost));
}
}
}
$this->est_part_idArr=htmlspecialchars(strip_tags($this->est_part_idArr));
$this->part_qtyArr=htmlspecialchars(strip_tags($this->part_qtyArr));
$this->part_numArr=htmlspecialchars(strip_tags($this->part_numArr));
$this->part_discArr=htmlspecialchars(strip_tags($this->part_discArr));
$this->part_costArr=htmlspecialchars(strip_tags($this->part_costArr));
$stmt->bindParam(":est_part_id", $this->est_part_idArr[0]);
$stmt->bindParam(":part_qty", $this->part_qtyArr[0]);
$stmt->bindParam(":part_num", $this->part_numArr[0]);
$stmt->bindParam(":part_disc", $this->part_discArr[0]);
$stmt->bindParam(":part_cost", $this->part_costArr[0]);
if($stmt->execute()){
return true;
}else{
return false;
}
}
At this point I know
public $est_part_idArr;
public $part_qtyArr;
public $part_numArr;
public $part_discArr;
public $part_costArr;
is wrong I just cant get anything to work.
You are missing some $this in front of your variables to access your public class members. Let us take this line for example:
$est_part_id = $est_part_idArr[$i];
which in my opinion should look like this:
$est_part_id = $this->est_part_idArr[$i];
On the other hand when you bind your parameters some lines down the code you're using something like this:
$stmt->bindParam(":est_part_id", $this->est_part_id);
Which I believe should be
$stmt->bindParam(":est_part_id", $this->est_part_idArr);
or
$stmt->bindParam(":est_part_id", $this->est_part_idArr[0]);

PHP Method in Class not returning data from database

Ok this should be fairly simple.
I have a table which contains content of 3 different textboxes the method inside my class should get the content to insert into textboxes.
Example TextBoxes (TextArea) where content should be entered.
My Method
public function LoadBoxes(){
$db = DB::getInstance();
$sql = "SELECT * FROM beta_letsgocontent";
$stmnt = $db->prepare($sql);
$stmnt->execute();
$boxes = $stmnt->fetchAll();
foreach ($boxes as $box) {
$data[] = array('Low' => $box['boxLow'],
'Medium' => $box['BoxMedium'],
'High' => $box['BoxHigh']);
}
return $data;
}//function
Here is my table (image below) so data / content from table should get inserted into the textboxes.
So when I do a test on content.php where I call the class method as such:
require_once('../classes/class.content.php');
$boxes = new Contents();
$boxes->LoadBoxes();
var_dump($boxes);
I get the following back:
Problem
As can be seen the array keys get returned however the data from database is not matched to array keys or returned by the method...I am stumped and have no idea what I am doing wrong here?
Any suggestions where I am going wrong? Could it be that I am not connecting to database correctly?
However if it was a database connection error I believe I would have received an error
Please keep in mind im a student and still learning.
UPDATE
Connection Schema
class Db {
private static $instance = NULL;
private function __construct() {}
private function __clone() {}
public static function getInstance() {
if (!isset(self::$instance)) {
$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
self::$instance = new PDO('mysql:host=localhost;dbname=beta', 'root', '', $pdo_options);
}
return self::$instance;
}
}
UPDATE 2
I just did the following on a test.php page which returned correct results.
require('connection.php');
function LoadBoxes(){
$db = DB::getInstance();
$sql = "SELECT * FROM beta_letsgocontent";
$stmnt = $db->prepare($sql);
$stmnt->execute();
$boxes = $stmnt->fetchAll();
foreach ($boxes as $box) {
$box[] = array('Low' => $box['BoxLow'],
'Medium' => $box['BoxMedium'],
'High' => $box['BoxHigh']);
}
return $box;
}//function
print_r(LoadBoxes());
?>
2 issues primary issues;
You're returning $data from the class but not populating a variable with the returned array.
You are var dumping the object itself.
This should work;
require_once('../classes/class.content.php');
$boxes = new Contents();
$data = $boxes->LoadBoxes();
var_dump($data);

Multiple database connections using multiton or any design pattern

I have following code for multiple database connections. It's not good design. Everything is static. But don't know how to improve it. i can add more functions like prepare query, but presently I want good/clean design. I tried to make multiton design pattern. The requirements is like, first I will connect with 1 database, then get database details of all other mysql clients, then loop and connect with each database and do something. So, I need multiple connections.
<?php
class db_class{
private static $instance = array();
private function __construct(){ }
public static function get_instance($type , $db_detail_array=array()){
$host = $db_detail_array['host'];
$username = $db_detail_array['username'];
$database = $db_detail_array['database'];
$password = $db_detail_array['password'];
if(empty($host) or empty($username) or empty($database) or empty($password)){
return;
}
if(empty(self::$instance[$type])) {
self::$instance[$type] = new mysqli($host, $username, $password, $database);
if (#self::$instance[$type]->connect_errno) {
echo self::$last_err = "Connect failed";
}
}
}
static function fetch_assoc($query,$type){
$db_query = self::run_query($query,$type);
$rows = array();
while($row = #$db_query->fetch_assoc()){
$rows[] = $row;
}
$db_query->free();
return($rows);
}
static function escape($type,$value){
$value = self::$instance[$type]->real_escape_string($value);
return($value);
}
static function run_query($query,$type){
self::$instance[$type]->ping();
$db_query = self::$instance[$type]->query($query);
if(self::$instance[$type]->error){
echo self::$last_err = self::$instance[$type]->error;echo "<p>$query, $type</p>";
return;
}
return($db_query) ;
}
static function num_rows($query,$type){
$db_query = self::run_query($query,$type);
$num_rows = $db_query->num_rows;
return($num_rows);
}
static function disconnect($type){
#self::$db_obj[$type]->close();
}
}
?>
Please have a look at PDO.
It is an unifier database object exposing a common and effective interface.
It supports server types other than mysql too.
Even using it plainly will be satisfactory.

Can't pass mysqli object to class in PHP

So I'm working on a simple user class in php, which has a class variable which contains the mysqli object, however I keep getting the error:
Fatal error: Call to a member function real_escape_string() on a non-object in */classes/user.php on line X
I've checked everything, it should work, but it doesn't. Somehow. This is my code:
namespace bibliotheek;
class user
{
private $mysql;
private $logged_in = false;
private $user_data = null; //ARRAY: user_id, e-mail, password, bevoegdheid, naam, achternaam, adres, postcode, stad
function __construct(\mysqli $mysql, $salt)
{
$this->mysql = $mysql;
}
public function login($email, $pass, $hash = false)
{
$email = $this->mysql->real_escape_string($email);
if($hash == false)
$pass = sha1($this->salt.$pass);
$query = "SELECT *
FROM gebruikers
WHERE gebruikers.email = '$email' AND gebruikers.password = '$pass'";
$result = $this->mysql->query($query);
$user_data = $result->fetch_assoc();
if($user_data == null)
return;
$this->logged_in = true;
$this->user_data = $user_data;
$this->create_cookies($email, $pass);
}
}
And this is how the mysqli object gets passed to the class:
$mysql = new mysqli($cfg['mysql_server'], $cfg['username'], $cfg['password'], $cfg['database']);
$user = new bibliotheek\user($mysql, $cfg['salt']);
the mysql login data is correct, I've made sure of that.
I must be missing something really obvious here, but I just can't see it. Any help is greatly appreciated. Thanks!
And this is how it should be
error_reporting(E_ALL);
$mysql = new mysqli($cfg['mysql_server'], $cfg['username'], $cfg['password'], $cfg['database']);
if ( !$mysql )
{
throw new Exception(mysqli_connect_error()));
}
$user = new bibliotheek\user($mysql, $cfg['salt']);
I'm really f-ing stupid, I compacted my code a bit when I posted it on here and I left out this part:
$this->mysql = $mysql;
$this->mysql = $salt;
Kill me now.

PDO Problem -> Call to a member function on a non-object

I have been turning and twisting this to the best of my non-existing PDO knowledge, but still without any luck.
the code:
function write($id, $data) {
global $dbcon;
$id = mysql_real_escape_string($id);
$data = mysql_real_escape_string($data);
$sql = $dbcon->exec("INSERT INTO `sessions`
(`session_id`, `session_data`,
`session_expire`, `session_agent`,
`session_ip`, `session_referrer`)
VALUES
(\"".$id."\", \"".$data."\",
\"".time()."\",\"".($this->session_encryption($_SERVER['HTTP_USER_AGENT']))."\",
\"".($this->session_encryption($_SERVER['REMOTE_ADDR']))."\", \"".($this->session_encryption((isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_^~#&|=+;!,(){}[].?%*#'))))."\")
ON DUPLICATE KEY UPDATE
`session_data` = \"".$data."\",
`session_expire` = \"".time()."\"");
return true;
}
Give me the following error:
Fatal error: Call to a member function exec() on a non-object
on the
$sql = $dbcon->exec(
line.
I have been trying to solve this all evening, but without any luck.
This is my PDO connection script:
require_once(INC_PATH.'/config.php');
$dsn = "$db_type:host=$db_host;port=$db_port;dbname=$db_name;charset=$db_charset";
try{
$dbcon = new PDO($dsn, $db_user, $db_pass);
$dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//$dbcon = null; //Close database connection.
}
catch(PDOException $e){
echo $e->getMessage();
}
Hope one of you kind souls out there can help me, I would deeply appreciate it!
Thanks.
UPDATE:
I have a global.php file which looks like this:
//Load database
require_once(INC_PATH.'/database.php');
//Load session handler
require_once(INC_PATH.'/class_sessions.php');
$Sessions = new SessionManager();
session_start();
The database.php is included before the sessions class, and when I view the website, it does not give any errors on this part of the sessions class (which is before the write function:
function read($id) {
global $dbcon;
$data = '';
$id = mysql_real_escape_string($id);
$sql = $dbcon->prepare("SELECT
`session_data`
FROM
`sessions`
WHERE
`session_id` = '".$id."'");
$sql->execute();
$a = $sql->columnCount();
if($a > 0) {
$row = $sql->fetchObject();
$data = $row['session_data'];
}
return $data;
}
Are you sure your connection script is getting executed? Try checking if $dbcon is set. Also, you may be missing global $dbcon within the connection script.
By the way, since you're already using PDO, might I recommend you use placeholders in your query:
$sql = "INSERT INTO `sessions`
(`session_id`, `session_data`, `session_expire`,
`session_agent`, `session_ip`, `session_referrer`)
VALUES
(:session_id, :session_data, :session_expire,
:session_agent, :session_ip, :session_referrer)
ON DUPLICATE KEY UPDATE
`session_data` = :session_data,
`session_expire` = :session_expire";
$params = array(
':session_id' => $id,
':session_data' => $data,
':session_expire' => time(),
':session_agent' => $this->session_encryption($_SERVER['HTTP_USER_AGENT']),
':session_ip', => $this->session_encryption($_SERVER['REMOTE_ADDR']),
':session_referrer' => $this->session_encryption((isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_^~#&|=+;!,(){}[].?%*#';
);
$stmt = $dbcon->prepare($sql);
if ($stmt->execute($params) === FALSE) {
// handle error
}
First check that the global object is not being overwritten by another function. I strongly suggest you use Dependency injection instead of globals.
$Sessions = new SessionManager($dbcon);
And inside the Session Management class you can do something like
class SessionManager
{
protected $db;
public function __construct($db) { $this->db = $db; }
public function read($id)
{
$stmt = $this->db->prepare("SELECT session_data
FROM sessions
WHERE session_id = ?");
$stmt->execute(array($id));
return $stmt->fetchColumn();
}
}
And secondly, since you are using PDO, you dont need to call mysql_real_escape_string(), use prepared statements and placeholders :)

Categories