DB pulling Function with PHP - php

I am very new to programming with PHP and am working on a fun little game to help myself learn. I got some code help from others on pulling a character's stats from the DB but am having trouble getting it to work. I just get "server error" when I try to run it right now. The Database information is fine, and I previously had a working function that pulled from the DB, but wanted to universalize it through a class function. Here is what I have so far.
DB class:
<?php
class db_class
{
//db connection portion
protected $mysqli;
private $db_host = 'XXXXXXX';
private $db_user = 'Filler';
private $db_password = 'Filler';
protected $db_name = 'Filler';
//db connection portion
public function __construct($db_host = null, $db_user = null, $db_password = null, $db_name = null) {
if (!empty($db_host)) {
$this->db_host = $db_host;
}
// validate other parameters similarly
//database connection object
$mysqli = new mysqli($this->db_host, $this->db_user, $this->db_password, $this->db_name);
if ($mysqli->connect_error) {
throw new Exception('Connect Error: ' . $mysqli->connect_errno . ', ' . $mysqli->connect_error);
} else {
$this->mysqli = $mysqli;
}
}
public function getPlayerStats($id) {
if (empty($id)) {
throw new Exception ('An empty value was passed for id');
}
// verify this is integer-like value
$id = (string) $id;
$pattern = '/^\d+$/';
if (!preg_match($pattern, $id) !== 1) {
throw new Exception ('A non-integer value was passed for id');
}
$id = (int) $id;
$query = "SELECT id, name, strength, defense, level, health, type, experience FROM characters WHERE id = :id";
$stmt = $this->mysqli->prepare($query);
$stmt->bind_param('i', $id);
$result = $stmt->execute();
if (false === $result) {
throw new Exception('Query error: ' . $stmt->error);
} else {
$obj = new stdClass();
$stmt->bind_result($obj->id, $obj->name, $obj->strength, $obj->defense, $obj->level, $obj, health, $obj->type, $obj->experience);
$stmt->fetch();
$stmt->close();
return $obj;
}
}
}
?>
DB class function call:
<?php
include "db_class.php";
echo "made it out here1";
$classobject = new db_class();
echo "made it out here2";
$results = $classobject->getPlayerStats('1');
print_r($results);
echo "made it out here3";
$id = "id: " . $results['id'];
$name = "name: " . $results['charname'];
$strength = "strength: " . $results['strength'];
$defense = "defense: " . $results['defense'];
$health = "health: " . $results['health'];
$level = "level: " . $results['level'];
$type = "type: " . $results['type'];
$experience = "experience: " . $results['experience'];
echo "<br/>";
echo "made it out here4";
?>
It is difficult to debug this code since I'm used to just putting in breaklines and running through coding errors in things like VBA in compilers, so any debugging tips would be greatly helpful. What am I doing wrong here? Thanks in advance!

You wrote
public __construct($db_host = NULL, ...
but constructors are functions. You need
public function __construct($db_host = NULL, ...
Your db_class constructor accepts four parameters. This instantiation passes none.
$classobject = new db_class();
So you end up with junk in your connection string. Sort that out and you'll be on your way.
You can avoid a lot of debugging by building minimal versions that work. For example, you can write this first.
<?php
class db_class{
public function __construct($db_host = NULL, $db_user = NULL, $db_password = NULL, $db_name = NULL) {
}
}
?>
If that works, check it in to version control, then add a little code to it. (How do you know whether it works? Test it.)

Related

Uncaught Error: Call to a member function prepare() (PDO, php)

I'm trying to get data from a table using a public function in PHP, but I get this error:
Uncaught Error: Call to a member function prepare() (PDO, php)
I'm searching for 2, 3 hours... But no result is similar or I did not understand.
<?php
class Config {
public static $SQL;
private function __construct() {
$host_name = "localhost";
$base_user = "root";
$base_pass = "";
$base_name = "home_page";
try {
self::$SQL = new PDO("mysql:host=$host_name;dbname=$base_name", $base_user, $base_pass);
self::$SQL->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
die("Something went wrong, database connection closed. Reason: ". $e->getMessage());
}
}
public static function GetData($table, $data, $id) {
$wc = Config::$SQL->prepare('SELECT `'.$data.'` FROM `'.$table.'` WHERE `ID` = ?');
$wc->execute(array($id));
$r_data = $wc->fetch();
return $r_data[$data];
}
}
?>
And I use this in my base file:
<h1><?php echo Config::GetData("page_details", "Moto", 1) ?></h1>
The error is from this line:
$wc = self::$SQL->prepare('SELECT `'.$data.'` FROM `'.$table.'` WHERE `ID` = ?');
Is there any particular reason why you want to use STATICeverywhere? The common approach is using public, dynamic methods and properties. I rewrote your sample with suggested naming convention in PHPs OOP, it works:
<?php
class Config
{
/** #var PDO $conn */
private $conn = null;
public function __construct()
{
$host_name = "localhost";
$base_user = "root";
$base_pass = "";
$base_name = "home_page";
try {
$this->conn = new PDO("mysql:host=$host_name;dbname=$base_name", $base_user, $base_pass);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully"; // <- this is unnnesesary
} catch (PDOException $e) {
die("Something went wrong, database connection closed. Reason: " . $e->getMessage());
}
}
public function findById($table, $data, $id)
{
$stmt = $this->conn->prepare('SELECT `' . $data . '` FROM `' . $table . '` WHERE `uid` = ?');
$stmt->execute(array($id));
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
// just for test
$cfg = new Config();
print_r($cfg->findById('foo', '*', 1));
or in your case
<?php echo $cfg->findById("page_details", "Moto", 1)['Moto'] ?>

OOP PHP Database results to Array

I am new to the idea of oop php and i am trying to write an irc php.
What I'm trying to do:
I am trying to query my database, get results from my database and put it into an array inside my program.
I tried making a new function to carry out the task and called it in the __construct function.
I have shortened the code but it pretty much looks like this:
Any thoughts and ideas are much appreciated.
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
function __construct()
{
//create new instance of mysql connection
$conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($mysqli->connect_errno)
{
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";
$this->database_fetch();
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($query);
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row();
}
}
function main()
{
print_r($array);
}
}
$bot = new IRCBot();
Changes
1) Change if ($mysqli->connect_errno) to if ($conn->connect_errno)
2) Change $array[] = $row(); to $array[] = $row;
3) Add return $array; in function database_fetch()
4) Call database_fetch() function inside main() function instead of constructor.
5) Add $this->conn in mysqli_query() (Thanks #devpro for pointing out.)
Updated Code
<?php
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
public $conn;
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
while($row = mysqli_fetch_assoc($result)){
$array[] = $row;
}
return $array;
}
function main()
{
$data = $this->database_fetch();
print_r($data);
}
}
Quick Start
Object Oriented Programming in PHP
Classes and Objects
Principles Of Object Oriented Programming in PHP
First of all you need to fix error from your constructor, you can modify as:
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
echo $this->conn->host_info . "\n";
}
Here, you need to replace $mysqli with $conn because your link identifier is $conn not $mysqli
No need to call database_fetch() here.
You need to use $conn as a property.
Now you need to modify database_fetch() method as:
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
$array = array();
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row;
}
return $array;
}
Here, you need to pass add first param in mysqli_query() which should be link identifier / database connection.
Second, you need to use return for getting result from this function.
In last, you need to modify your main() method as:
function main()
{
$data = $this->database_fetch();
print_r($data);
}
Here, you need to call database_fetch() method here and than print the data where you need.

php function with 2 arguments

I have a function with 2 arguments. Here it is
function listBoats($con,$table){
//get record set for all boats sort them by their "sort" number
$queryBoat = "SELECT * FROM " .$table. " WHERE `id` <> 'mainPage' ORDER BY `sort` LIMIT 0, 1000";
$result = mysqli_query($con,$queryBoat);
return $result;
}
here is how I'm calling it
$result = listBoats($con,"CSINSTOCK"); //run query to list all the boats in the CSINSTOCK table
I can't get it to work. But If I add the variable $table = "CSINSTOCK" inside the function it does work. Why wont the function pass the "CSINSTOCK" variable through?
I would suggest that you use PDO. Here is an example
EXAMPLE.
This is your dbc class (dbc.php)
<?php
class dbc {
public $dbserver = 'server';
public $dbusername = 'user';
public $dbpassword = 'pass';
public $dbname = 'db';
function openDb() {
try {
$db = new PDO('mysql:host=' . $this->dbserver . ';dbname=' . $this->dbname . ';charset=utf8', '' . $this->dbusername . '', '' . $this->dbpassword . '');
} catch (PDOException $e) {
die("error, please try again");
}
return $db;
}
function getAllData($qty) {
//prepared query to prevent SQL injections
$query = "select * from TABLE where qty = ?";
$stmt = $this->openDb()->prepare($query);
$stmt->bindValue(1, $qty, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
?>
your PHP page:
<?php
require "dbc.php";
$getList = $db->getAllData(25);
foreach ($getList as $key=> $row) {
echo $row['columnName'] .' key: '. $key;
}
If you have the access to your database you should be able to perform your required operations.

using class method to pull database info

Overview: I have a function that is supposed to pull a row of the db based on its id number
Problem: It seems my function is returning, but it isn't returning anything.
Details:
-I have 2 different files used here: db_class.php and character_pull.php
-Also I have a database that contains 1 table (characters) that does contain column "id"
-there are echo lines for debugging. I will give what the output is.
character_pull.php:
<?php
include "db_class.php";
echo "made it out here1";
$classobject = new db_class();
echo "made it out here2";
$results = $classobject->getPlayerStats("1");
print_r($results);
echo "made it out here3";
$id = "id: " . $results['id'];
$name = "name: " . $results['charname'];
$strength = "strength: " . $results['strength'];
$defense = "defense: " . $results['defense'];
$health = "health: " . $results['health'];
$level = "level: " . $results['level'];
$type = "type: " . $results['type'];
$experience = "experience: " . $results['experience'];
echo"<br/>";
echo "made it out here4";
?>
db_class.php:
<?php
include "database_connect.php";
class db_class{
public function getPlayerStats($id){
echo "<br/>" . "making it in class1";
$query = "SELECT * FROM characters WHERE id = $id";
$result = mysqli_query($query);
return $char = mysqli_fetch_array($result);
$result ->close();
}
}
?>
the output I receive when I run the page is this:
made it out here1made it out here2 making it in class1made it out
here3 made it out here4
I have tried several things to fix this, but am having trouble figuring out what is wrong.
I know that this is probably extremely sloppy and primitive, but try not to laugh too hard and maybe you can help me out :P. Thanks in advance.
You have a number of issues here.
It seems your DB class is quite incomplete. To me, if I am creating a class to represent a DB connection and various operations I am going to make that connection in that class, not via some include (where I assume the connection is happening). The here is that the include will only occur conditionally if your code hits that line. In this case, since you have that include outside any actual function in the class (like a constructor) it will never be called.
I would suggest something like this to resolve this:
class db_class {
protected $mysqli;
private $db_host = 'your_db_host';
private $db_user = 'your_db_user';
private $db_password = 'your_db_password';
protected $db_name = 'default_db_name';
public __construct($db_host = NULL, $db_user = NULL, $db_password = NULL, $db_name = NULL) {
if (!empty($db_host)) {
$this->db_host= $db_host;
}
// validate other parameters similarly
$mysqli = new mysqli($this->db_host, $this->db_use, $this->db_password, $this->db_name);
if($mysqli->connect_error) {
throw new Exception('Connect Error: ' . $mysqli->connect_errno . ', ' . $mysqli->connect_error);
} else {
$this->mysqli = $mysqli;
}
}
// other class methods
}
You now have an object representing a mysqli connection store in $this->mysqli.
Your getPlayerStats() method might now look like
public function getPlayerStats($id) {
if(empty($id)) {
throw new Exception ('An empty value was passed for id');
}
// verify this is integer-like value
$id = (string)$id;
$pattern = '/^\d+$/';
if (!preg_match($pattern, $id) !== 1) {
throw new Exception ('A non-integer value was passed for id');
}
$id = (int)$id;
$query = "SELECT id, name, strength, defense, level, health, type, experience FROM characters WHERE id = :id";
$stmt = $this->mysqli->prepare($query);
$stmt->bind_param('i', $id);
$result = $stmt->execute();
if (false === $result) {
throw new Exception('Query error: ' . $stmt->error);
} else {
$obj = new stdClass();
$stmt->bind_result($obj->id, $obj->name, $obj->strength, $obj->defense, $obj->level, $obj, health, $obj->type, $obj->experience);
$stmt->fetch();
$stmt->close();
return $obj;
}
}
Note I used prepared statements here, which, you should get used to using as it is really best practice for querying databases. Note also I have added in handling of error cases all throughout the code. You should get in the habit of doing this, as it will making debugging much easier.
Just a guess but I would move this above the class name:
<?php
include "database_connect.php";
class db_class{

store multiple pdo connections in an array

so i have been trying to debug this issue myself for a few days now and i can't seem to figure out why i'm not getting the results I expect.
My code is rather complex and for a DB connection to be establish it spans across 3 Classes and one config file.
but basically my end usage ends up being
$this->db('test')->query('SELECT * FROM test1');
this establishes a connection to my database by the alias of test the query returns results so i'm good so far.
now my issue is when i try to make a new PDO object.
$this->db('test2')->query('SELECT * FROM test2');
this returns nothing because there is not table called test2 in my test1 object.
but if I do this
$this->db('test2')->query('SELECT * FROM test1');
now this returns the same results from the first PDO object.
I have traced and tracked down every line of code to make sure that the correct parameters are being passed to my database class and that each connection is properly established to the corresponding databases.
now my question is, can you have more than one datbase pdo connection? if so is there a special flag that needs to be set in the PDO options? are my connections being cached somewhere and causing this confusion?
this is my PDO declaration in each new class object stored in my array of connections
try
{
$this->_con = new PDO(
"mysql:host=" . $host . ";
port=" . $port . ";
dbname=" . $name, $user, $pass
);
$this->_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
// TODO: push all $e methods to the developer debugger
echo "Database Error: ". $e->getMessage();
}
edit my code that uses the connection
step 1: a call to the parent class
public function __call($name, $params)
{
$class = $name . '_system_helper';
$hash = md5($class . $params);
if (class_exists($class))
{
if (!array_key_exists($hash, $this->_sys_helper))
{
if (method_exists($class, 'init'))
{
$this->_sys_helper[$hash] = call_user_func_array(array($class, 'init'), $params);
} else {
$this->_sys_helper[$hash] = call_user_func_array($class, $params);
}
}
return $this->_sys_helper[$hash];
}
return null;
}
step 2: called from the parent class
class DB_System_Helper extends Jinxup
{
private $_con = null;
public function __construct($end = null)
{
$mode = null;
$host = null;
$name = null;
$user = null;
$pass = null;
$port = null;
if (isset($this->config['database']['mode']))
{
$mode = $this->config['database']['mode'] == 'production' ? 'production' : 'development';
if (count($this->config['database'][$mode]) > 1)
{
foreach ($this->config['database'][$mode] as $key => $database)
{
if ($database['#attr']['alias'] == $end)
{
$host = $this->config['database'][$mode][$key]['host'];
$name = $this->config['database'][$mode][$key]['name'];
$user = $this->config['database'][$mode][$key]['user'];
$pass = $this->config['database'][$mode][$key]['pass'];
$port = $this->config['database'][$mode][$key]['port'];
}
}
} else {
$host = $this->config['database'][$mode]['host'];
$name = $this->config['database'][$mode]['name'];
$user = $this->config['database'][$mode]['user'];
$pass = $this->config['database'][$mode]['pass'];
$port = $this->config['database'][$mode]['port'];
}
$this->_con = new PDO_Database_Helper($host, $name, $user, $pass, $port);
} else {
echo 'No database mode specified';
}
}
public function __call($name, $param)
{
return call_user_func_array(array($this->_con, $name), $param);
}
}
step 3: called from DB_System_Helper
class PDO_Database_Helper extends Jinxup
{
private $_con = null;
private $_id = 0;
public function __construct($host, $name, $user, $pass, $port = 3306)
{
try
{
$this->_con = new PDO(
"mysql:host=" . $host . ";
port=" . $port . ";
dbname=" . $name, $user, $pass
);
$this->_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
// TODO: push all $e methods to the developer debugger
echo "Database Error: ". $e->getMessage();
}
}
[...]
}
Are you sure that the hashing you're doing is enough to "namespace" each connection in the $this->_sys_helper array?
I suspect the problem lies in the first stage.
public function __call($name, $params)
{
$class = $name . '_system_helper';
$hash = md5($class . $params);
if (class_exists($class))
{
if (!array_key_exists($hash, $this->_sys_helper))
{
if (method_exists($class, 'init'))
{
$this->_sys_helper[$hash] = call_user_func_array(array($class, 'init'), $params);
} else {
$this->_sys_helper[$hash] = call_user_func_array($class, $params);
}
}
>>>>>>>>>>>>>> are you sure this is not returning the wrong
>>>>>>>>>>>>>> connection because of how the hashing is working?
return $this->_sys_helper[$hash];
}
return null;
}

Categories