I have a class named player that creates, deletes and controls if a player entity exists. In another file, I have the database connection with PDO and, finally, in third file I have the call to player class. Here's all the code:
file: player.php
<?php
class player
{
private $pdo;
private $network_id;
public $color;
public function __construct($pdo, $network_id, $color)
{
$this->pdo = $pdo;
$this->network_id = $network_id;
$this->color = $color;
}
public function create_player()
{
if(!$this->exists_player())
{
$sql = 'INSERT INTO players SET network_id = :network_id';
$query = $this->pdo->prepare($sql);
$query->execute(array(':network_id' => $this->network_id));
}
else
{
echo 'error';
}
}
public function delete_player()
{
if($this->exists_player())
{
$sql = 'DELETE FROM players WHERE network_id = :network_id';
$query = $this->pdo->prepare($sql);
$query->execute(array(':network_id' => $this->network_id));
}
else
{
return -1;
}
}
private function exists_player()
{
$sql = 'SELECT COUNT(*) FROM players WHERE network_id = '.$this->network_id;
$result = $this->pdo->exec($sql);
if($result > 0) return true;
else return false;
}
}
?>
file: test.php
<?php
include './Php/db_connection.php';
include './Php/player.php';
$player = new player($pdo, 1112, 'red');
$player->create_player();
?>
file: db_connection.php
$pdo = new PDO('mysql:host=localhost; dbname=myDbName', 'dbUtent', 'myPassword');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
The thing is that when I call test.php, I get this error:
Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in F:\Software\Coding_Development_Software\Server\wamp\www\myProject\Ajax\Cube\Php\player.php on line 21
All code is an exemple.
Any ideas?
The thing here is that you need to fetch until it fails for a row fetch attempt. In fact, your own exception is telling you the solution:
Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in F:\Software\Coding_Development_Software\Server\wamp\www\myProject\Ajax\Cube\Php\player.php on line 21
Related
This question already has answers here:
How can I fix MySQL error #1064?
(3 answers)
How can I prevent SQL injection in PHP?
(27 answers)
Closed 2 years ago.
im new here and im also pretty new to php and OOP so if i dont ask the right question also tell me ;p
im trying to make a class that handles all the queries from and to the database. I want to make this class as reusable as plossible so i dont have to keep writing selects and insert statements in all my methods and functions.
my question is: is it plossible to call on an method with parameters and then have those parameters finish the query for me ?
this is what i had come up with so far:
Database connection class:
class Database {
private $host;
private $user;
private $pass;
private $dbname;
private $charset;
public function connect() {
$this->host = 'localhost:3306';
$this->user = 'root';
$this->pass = '';
$this->dbname = 'Testdb';
$this->charset = 'utf8mb4';
try {
$dsn = 'mysql:host='.$this->host.';dbname='.$this->dbname.';charset='.$this->charset;
$pdo = new PDO($dsn, $this->user, $this->pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch (PDOException $e) {
echo "Connection failed:".$e->getMessage();
}
}
}
this is my query's class:
class QueryDatabase extends Database {
public function getData($tablename, $selector, $value) {
if (!isset($selector)){
echo 'Something went wrong!';
} else if ($selector == ''){
$stmt = $this->connect()->query("SELECT * FROM $tablename");
while ($row = $stmt->fetch()){
return $row;
}
}else {
$stmt = $this->connect()->query("SELECT * FROM $tablename where $selector = $value");
while ($row = $stmt->fetch()){
return $row;
}
}
}
public function setData($tablename, $colums, $data) {
if (!isset($tablename) or !isset($data)) {
echo 'Something went wrong!';
} else {
$sql = "INSERT INTO $tablename ($colums) VALUES ($data)";
$q = $this->connect()->prepare($sql);
$q->execute();
}
}
protected function addData() {
}
protected function delData() {
}
}
and this is what i mean with the parameters for example:
$test = new QueryDatabase;
$test->setData('contact_form_messages', 'u_id, name, email, subject, message, date', ' , Kees, Kees#gmail.com, Test, Hopefully it works, ');
i get this error message :
Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' Kees, Kees#gmail.com, Test, Hopelijk werkt hij, )' at line 1 in D:\webProjects\project\classes\querydatabase.class.php:31
Stack trace: #0 D:\webProjects\project\classes\querydatabase.class.php(31): PDOStatement->execute() #1 D:\webProjects\project\includes\header.inc.php(5):
QueryDatabase->setData('contact_form_me...', 'u_id, name, ema...', ' , Kees, Kees#g...') #2 D:\webProjects\project\contact.php(1): include('D:\\webProjects\\...') #3 {main} thrown in D:\webProjects\project\classes\querydatabase.class.php on line 31
if you have any suggestions i'd be happy to hear them!
thanks a lot!
Floris
I'm trying to write a PHPUnit test function on the school project I'm working on. The functions work fine with the normal web site. But when I try to test database related operations with PHPUnit, I keep getting mysqli_query(): Couldn't fetch mysqli.
Here is the a sample code snippet:
PHPUnit File: test.php
function testFindById() {
$expected_object = "Artist";
$result = Artist::find_by_id($id);
$result_type = gettype($result);
$this->assertEquals($expected_object, $result_type);
}
DatabaseHelper Class: DatabaseHelper.php
public static function find_by_sql($sql) {
global $database;
$result = $database->query($sql);
$objects = array();
if ($result) {
while ($row = mysqli_fetch_array($result)) {
$objects[] = static::new_instance($row);
}
}
return $objects;
}
public static function find_by_id($id) {
global $database;
$sql = "SELECT * FROM " . static::$table_name . " WHERE id = $id LIMIT 1";
$result = static::find_by_sql($sql);
if (!empty($result)) {
return array_shift($result);
} else {
return false;
}
}
Artist Class: Artist.php
class Artist extends DatabaseHelper {
protected static table_name = "artists";
// more irrelevant code follows
}
TEST OUTPUT
C:\Xampp\htdocs\musicstore-oop-beta\test>phpunit --verbose MusicStoreTest.php
PHPUnit 3.7.21 by Sebastian Bergmann.
SSE
Time: 0 seconds, Memory: 2.00Mb
There was 1 error:
1) MusicStoreTest::testFindById
mysqli_query(): Couldn't fetch mysqli
C:\Xampp\htdocs\musicstore-oop-beta\app\Database.php:38
C:\Xampp\htdocs\musicstore-oop-beta\app\DatabaseHelper.php:23
C:\Xampp\htdocs\musicstore-oop-beta\app\DatabaseHelper.php:37
C:\Xampp\htdocs\musicstore-oop-beta\test\MusicStoreTest.php:62
There were 2 skipped tests:
1) MusicStoreTest::testAddArtist
Artist Add Test Skipped
C:\Xampp\htdocs\musicstore-oop-beta\test\MusicStoreTest.php:24
2) MusicStoreTest::testAddAlbum
Album Add Test Skipped
C:\Xampp\htdocs\musicstore-oop-beta\test\MusicStoreTest.php:40
FAILURES!
Tests: 3, Assertions: 0, Errors: 1, Skipped: 2.
This occurs when either the database variable (in your case $database) does not refer to a connected database. You should check that the database connection is valid:
$database = new mysqli('db_host','user','password','db_name');
if ($database->connect_errno) {
error_log("Errno: " . $mysqli->connect_errno . ':' . mysqli->connect_error);
}
This can also occur if the variable used to store the database object is not in scope. Say if global $database; statement were missing (not applicable to your code which has the statement) then $database would only have local function scope - it would be a different variable to the global $database variable.
I'm new to OOP programming, and I'm really lost with this what the title says. When I try to put the query in a class and in another file, I get errors in a file called Main.php and don't even know what to do to fix them:
Notice: Undefined variable: sth in Select.php on line 10
Fatal error: Cannot access empty property in Select.php on line 10
If I put the select in Connection.php, it returns the rows just fine, but with classes, I get those.
Here's my code:
Connection.php:
<?php
$hostname = 'localhost';
$username = 'user';
$password = 'pass';
function connectDB ($hostname, $username, $password){
$dbh = new PDO("mysql:host=$hostname;dbname=database", $username, $password);
return $dbh;
}
$dbh = connectDB ($hostname, $username, $password);
echo 'Connected to database <br/>';
Select.php:
<?php require_once 'Connection.php';
class Select {
public function select() {
$sql= "select * from table limit 10; <br/>";
echo $sql;
$select = $dbh->query($sql)->fetchall(PDO::FETCH_ASSOC);
foreach($this->$sth as $row){
echo $row['column']."<br/>";
}
}
}
The question is, how can I print the result from the query (for example from main.php, which has an autoloader), and why do I get those errors, when on a single file, they work just fine?
Edit:
<?php
$test = new Select($dbh);
echo $test->select();
?>
Besides the fixes in the replies, I included Connection.php into the main.php, changed the echo in Select.php to return and it works perfectly now. Adding this in case someone ever gets as lost as me.
You do not want to iterate over the query, but the result of that query. So this probably is what you are looking for:
<?php
class Select {
public function select() {
$sql= 'select * from table limit 10';
$select = $dbh->query($sql)->fetchall(PDO::FETCH_ASSOC);
foreach($select as $row){
echo $row['column']."<br/>";
}
}
}
And you also need to take care that the $dbh object is actually present inside that method. Either inject it into the object or specify it as method argument. So your full class will probably look something like that:
<?php
class Select {
private $dbh;
public function __construct($dbh) {
$this->dbh = $dbh;
}
public function select() {
$sql= 'select * from table limit 10';
$select = $this->dbh->query($sql)->fetchall(PDO::FETCH_ASSOC);
foreach($select as $row){
echo $row['column']."<br/>";
}
}
}
And you instantiate the object like that:
$selectObj = new Select($dbh);
Some general warning, though: Using PDO's fetchall() method is convenient, but carries a huge risk: it means that the full result set has to be copied into an array inside the php script. For bigger results that may lead to issues with memory usage (scripts getting terminated for security reasons). Often it is the better approach to use a while loop over a single row fetched from the result set in each iteration.
So I have this pdo.php file that contains my Database connection. This is the function:
function db() {
static $dbh;
if(!isset($dbh)) {
$dsn = sprintf('mysql:host=%s;dbname=%s', SHOP_DB_HOST, SHOP_DB_NAME);
try {
$dbh = new PDO($dsn, SHOP_DB_USER, SHOP_DB_PASSWORD);
} catch(PDOException $e) {
header('Status: 500 Internal Server Error');
echo '<b>Error:</b> Database connection failed.';
exit;
}
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->exec('SET NAMES utf8');
}
return $dbh;
}
And this is another file in which I need to use db():(It's detecting an ajax call and based on that, supposed to update information)
if(isset($_POST['updateTree'])) {
$page_id = $_POST['page_id'];
$parent_id = $_POST['parent_id'];
$customer_id = $_SESSION['customer_id'];
$stojkovQ = db()->prepare("
UPDATE
cms_pages
SET
topicId = :parent_id
WHERE
page_id = :page_id
AND
customer_id = :customer_id
");
$stojkovQ->execute(array(
'customer_id' => $customer_id,
'page_id' => $page_id,
'topicId' => $parent_id
));
echo 'updated';
}
So after after getting an "Fatal Error: Call to undefined function db()" even tho it's included in my header.php file(containing all the includes and config information for my site). If I try to include it again just above my query it yields another error(Cannot redeclare db())
Any lead towards the resolving of this problem will be of great help.
I've been trying to convert my application from using the depreciated mysql syntax to PDO for connecting to the database and performing queries, and it's been a pain so far.
Right now I have a class, db_functions.php, in which I'm trying to create a PDO connection to the database, as well as perform all the CRUD operations inside of.
Here is a sampling of the code:
db_functions.php
<?php
class DB_Functions {
private $db;
// constructor
function __construct() {
require_once 'config.php';
// connecting to mysql
try {
$this->$db = new PDO('mysql:host=localhost;dbname=gcm', DB_USER, DB_PASSWORD);
}
catch (PDOException $e) {
$output = 'Unable to connect to database server.' .
$e->getMessage();
exit();
}
}
// destructor
function __destruct() {
}
public function getAllUsers() {
try {
$sql = "select * FROM gcm_users";
//$result = mysql_query("select * FROM gcm_users");
$result = $this->$db->query($sql);
return $result;
}
catch (PDOException $e) {
$error = 'Error getting all users: ' . $e->getMessage();
}
}
With that code, i'm getting the following error:
Notice: Undefined variable: db in C:\xampp\htdocs\gcm\db_functions.php on line 12
Fatal error: Cannot access empty property in C:\xampp\htdocs\gcm\db_functions.php on line 12
Line 12 is:
$this->$db = new PDO('mysql:host=localhost;dbname=gcm', DB_USER, DB_PASSWORD);
How could I fix this so that I have a proper instance of a PDO connection to my database that I can use to create queries in other methods in db_functions, such as getAllUsers()
I used the answer found at How do I create a connection class with dependency injection and interfaces? to no avail.
TYPO
//$this->$db =
$this->db =
same here
//$this->$db->query($sql);
$this->db->query($sql);
and i also would use 127.0.0.1 instead of localhost to improve the performance otherwise making a connection will take very long... a couple of seconds just for connection...