I am trying to create a PDO object in a class and then use it in another file. The PDO Object gets created (as far as I understand) but I can not use it in the other file and I view these outputs:
PDO Object ( )
connection successful.
Fatal error: Uncaught Error: Call to undefined method
app\db\Connect::query() in /var/www/html/pdoTest/index.php:25 Stack
trace: #0 {main} thrown in /var/www/html/pdoTest/index.php on line 25
My code is as following:
index.php
<?php
ini_set('display_errors', '1');
require_once './vendor/autoload.php';
$con = new \app\db\Connect();
if (!$con)
{
echo 'no PDO object available.';
}else{
echo 'connection successful.' . '<br>';
}
connect.php
<?php
namespace app\db;
use PDO;
class Connect
{
public function __construct()
{
// set the connection variables
$host = 'localhost';
$dbname = 'pdoposts';
$username = 'root';
$password = 'root';
// create the DSN
$dsn = 'mysql:host=' . $host . ';dbname=' .$dbname;
// create PDO connection
try {
$con = new PDO($dsn, $username, $password);
print_r($con);
echo '<br>';
} catch(Exception $e) {
echo $e->getMessage();
}
return $con;
}
}
I have searched all over stackoverflow and other parts of internet but as it seems I am out of luck understanding what my problem is in using the created PDO object. Would you please help me understand it?
Related
Im getting the follow error from my elastic beanstalk application:
Fatal error: Uncaught Error: Class 'App\PDO' not found in
/var/app/current/crawler/app/SQLConnection.php:32 Stack trace: #0
/var/app/current/crawler/init.php(18): App\SQLConnection->connect() #1
{main} thrown in /var/app/current/crawler/app/SQLConnection.php on
line 32
The app runs perfectly locally (as is usually the case with errors).
All libraries and dependencies are included in the app I uploaded.
Can anyone see where I went wrong please?
The initialzation script to create DB tables:
<?php
require 'vendor/autoload.php';
require (__DIR__.'/app/SQLConnection.php');
require (__DIR__.'/app/SQLCreateTable.php');
require (__DIR__.'/app/SQLInsert.php');
require (__DIR__.'/app/SQLRetrieve.php');
require (__DIR__.'/app/SQLDelete.php');
use App\SQLConnection;
use App\SQLCreateTable;
use App\SQLInsert;
use App\SQLRetrieve;
use App\SQLDelete;
try {
//connect to DB
$sql = new SQLCreateTable((new SQLConnection())->connect());
//get list of tables
$tables = $sql->getTableList();
//check if required tables excist
if(in_array('results',$tables) && in_array('logs',$tables)){
echo "Tables already created. You will be redirected to the home page";
header( "refresh:5;url=/index.php" );
}else {
//create tables
try {
$sql->createTables();
echo "Tables succesfully created! You will be redirected to the home page";
header( "refresh:5;url=/index.php" );
} catch (\PDOException $e) {
echo "Failed to create tables: " . $e->getMessage();
}
}
} catch (\PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
Then the SQL connection script:
<?php
namespace App;
/**
* SQL connnection
*/
class SQLConnection {
/**
* PDO instance
* #var type
*/
private $pdo;
/**
* return in instance of the PDO object that connects to the SQLite database
* #return \PDO
*/
public function connect() {
$dbhost = $_SERVER['RDS_HOSTNAME'];
$dbport = $_SERVER['RDS_PORT'];
$dbname = $_SERVER['RDS_DB_NAME'];
$charset = 'utf8' ;
$dsn = "mysql:host={$dbhost};port={$dbport};dbname={$dbname};charset={$charset}";
$username = $_SERVER['RDS_USERNAME'];
$password = $_SERVER['RDS_PASSWORD'];
if ($this->pdo == null) {
try {
// $this->pdo = new \PDO("mysql:host=localhost;dbname=crawler", "root", "");
$this->pdo = new PDO($dsn, $username, $password);
// set the PDO error mode to exception
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
}
return $this->pdo;
}
}
The 'Init' script is at root level and the SQLconnection script is in a folder called "app".
Thanks guys!
Found the solution!
$this->pdo = new PDO($dsn, $username, $password);
Needs to change
$this->pdo = new \PDO($dsn, $username, $password);
If anyone knows exactly why this is the case, please share
I have searched the forum, but I have not found anything directly related to my issue. I am fairly new to PDOs and class OOP creation. I am trying to create a database connection class where I can instantiate the connection as needed. I having issues instantiating my connection.
File Organization:
parent directory (folder)
|
private (folder)
|
config.php
classes (folder)
|
class1.class.php
DatabaseConnection.class.php
db_cred.inc.php
public (folder)
|
search.php
Process:
I have created a database credential php file "db_cred.inc.php"
I have a database connection class called "DatabaseConnect" in "DatabaseConnect.class.php" file
I load those files as follows
require_once 'db_cred.inc.php'; in the "DatabaseConnect.class.php" file
spl_autoload_register for all of my class files
Expected actions:
When my "search.php" page request data from mysql via a pdo, a new database connection will instantiate a new connection via the "openConnection()" method.
The class "DatabaseConnection" will load the credentials from "db_cred.inc.php" as a sting and connect to the database
The class will then use the credentials to connect to the mysql database, and execute the requested pdo query returning the results and storing them into a variable "$row".
Issue:
When I execute the pdo, the following error is returned:
Uncaught TypeError: PDO::__construct() expects parameter 1 to be string, array given in private/classes/DatabaseConnect.class.php:21 Stack trace: #0 private\classes\DatabaseConnect.class.php(21): PDO->__construct(Array) #1 \public\search.php(53): DatabaseConnect->openConnection() #2 {main} thrown in \private\classes\DatabaseConnect.class.php on line 21
spl_autoload_register() in the config.php file
function my_autoload($class) {
if(preg_match('/\A\w+\Z/', $class)) {
require ('classes/' . $class . '.class.php');
}
}
spl_autoload_register('my_autoload');
Credential setup in "db_cred.inc.php"
<?php
// define an array for db connection.
define("DB", [
"DB_HOST" => "mysql:host=localhost",
"DB_USER" => "user",
"DB_PASS" => "pass",
"DB_DATABASE" => "mytestdb",
"DB_CHAR" => "utf8",
]);
?>
My class for database connection:
<?php
require_once 'db_cred.inc.php';
// creating db connection class
class DatabaseConnect {
private $server = 'DB_HOST';
private $database = 'DB_DATABASE';
private $pass = 'DB_PASS';
private $user = 'DB_USER';
private $opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
protected $con;
public function openConnection() {
**ERROR TAKES PLACE HERE**
try {
$this->con = new PDO([$this->server, $this->database, $this->user, $this->pass]);
return $this->con;
} catch(PDOExeption $e){
echo "ERROR: " . $e->getMessage(), (int)$e->getCode();
}
}
public function closeConnection() {
$this->con = null;
}
}
?>
PDO for search.php
<?php
$dbconn = new DatabaseConnect();
$pdo = $dbconn->openConnection();
$sql = "SELECT * FROM report";
foreach ($pdo->query($sql) as $row) {
echo " PI: ".$row['pi'] . "<br>";
}
?>
I am not sure what is causing the error. I am sure it is due to my inexperience with classes and oop. It appears that the config.php file is working fine. The class is identified by the request because the error happens inside the PDO __construct method. Please help.
UPDATE - MY WORKING SOLUTION
I hope this might help someone moving forward with a similar question. I am not finished with the development of this process, but this kicked in a huge door.
My revised class
<?php
// Associating db_cred.inc.php with class
require_once('db_cred.inc.php');
// Creating db connection class
class DatabaseConnect {
/*
!! Assigning defined constants per define('DB_CONSTANT', 'value') loaded from "db_cred.inc.php" file to variables
!! "db_cred.inc.php" should not be loaded into the "config.php" file
!! BECAUSE THE VALUES OF THE VARIABLES ($variable) ARE CONSTANTS (DB_CONSTANT), DO NOT USE SINGLE OR DOUBLE QUOTES. THE PDO __CONSTRUCT FUNCTION WILL IGNORE THE VALUE OF THE VARIABLE
*/
private $host = DB_HOST;
private $database = DB_DATABASE;
private $pass = DB_PASS;
private $user = DB_USER;
private $char = DB_CHAR;
// Setting attributes and storing in variable $opt
private $opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
// $con variable will store PDO connection and is set to NULL
private $con;
// Create Connection to database
public function openConnection() {
// Setting $con to null
$this->con = NULL;
// If $con is not NULL make it NULL
if ($this->con === NULL){
try {
// Establish DSN
$dsn = "mysql:host={$this->host};dbname={$this->database};charset={$this->char}";
// Complete the PDO connection
$this->con = new PDO($dsn, $this->user, $this->pass,$this->opt);
// Return the connection and store it in $con
return $this->con;
// Catch any exceptions and store in $e
} catch(PDOExeption $e){
// Echo error and Exception message
echo "ERROR: " . $e->getMessage(), (int)$e->getCode();
}
// If the try/catch block fails, echo that no connection was established
} else {
echo "ERROR: No connection can be established";
}
}
// Close connection and set it to NULL
public function closeConnection() {
if($this->con !== NULL){
$this->con = NULL;
}
}
// create CRUD subclass (Create, Read, Update, Delete)
}
?>
I changed "db_cred.inc.php" eliminating the array. I may revisit the idea.
<?php
// defining DB Credential CONSTANTS to be stored in variables and instantiated by connect class
define("DB_HOST", "localhost");
define("DB_USER", "user");
define("DB_PASS", "pass");
define("DB_DATABASE", "mytestdb");
define("DB_CHAR", "utf8");
// define an array for db connection.
/*define("DB", [
"DB_HOST" => "localhost",
"DB_USER" => "user",
"DB_PASS" => "pass",
"DB_DATABASE" => "mytestdb",
"DB_CHAR" => "utf8",
]);*/
?>
The error explains itself: You're passing an array where you should be using a string instead.
You need to change this line:
$this->con = new PDO([$this->server, $this->database, $this->user, $this->pass]);
To this, (specifies the DSN first):
$dsn = "mysql:dbname={$this->database};host:{$this->host}";
$this->con = new PDO($dsn, $this->user, $this->password);
I am trying to establish a PDO connection using the try block and then printing a success message after the connection gets established. My code is as follows:
index.php :
<?php
require_once './vendor/autoload.php';
$con = new \app\db\Connect();
if ($con)
{
echo 'connection successful.';
}
connect.php
<?php
namespace app\db;
class Connect
{
public function __construct()
{
// set the connection variables
$host = 'localhost';
$dbname = 'pdoposts';
$username = 'root';
$password = 'root';
// create the DSN
$dsn = 'mysql:host=' . $host . ';dbname=' .$dbname;
// create PDO connection
try {
static $con;
$con = new PDO($dsn, $username, $password);
} catch(Exception $e) {
echo $e->getMessage();
}
return $con;
}
}
My problem is that there is no way for me to use the $concreated in the try - catch command in the index.php file. I am very sorry if this question seems very basic and elemental one, but please help me understand how it can work. Thank you very much in advance.
Accoring to the answer below:
The solution here on stackoverflow
I just added the backslash right before PDO and made it to be \PDO and it is now working properly. The link below can help understanding PHP Callbacks and how they work better:
Using namespaces: fallback to global function/constant
I should have kept in mind the namespace from which I wanted to use PDO from. In this case, using a \ would tell php to use PDO from the Global Namespace and not from the namespace from which the code runs in (app\db).
https://plnkr.co/edit/ZNlAyky7TzT4jknpnoDJ?p=preview
here is a link to a plnkr with all my code written so far. I keep getting an
Fatal error: Cannot redeclare connect_to_db() (previously declared in
/var/www/html/News/config/dbconnect.php:5) in
/var/www/html/News/config/dbconnect.php on line 5
the plunkr wont have the folder structure because i could not figure out how to add folders however here is my code for dbconnect.php
<?php
$pdo = null;
function connect_to_db()
{
$dbengine = 'mysql';
$dbhost = 'localhost';
$dbuser = 'root';
$dbpassword = 'password';
$dbname = 'news';
try{
$pdo = new PDO("".$dbengine.":host=$dbhost; dbname=$dbname", $dbuser,$dbpassword);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
return $pdo;
}
catch (PDOException $e){
$e->getMessage();
}
}
line 5 does not have a call to db connect so i dont know what is going on
You are using
require __DIR__.'/dbconnect.php'
In both your Index.php and your functions.php, while requiring your functions.php in Index.php.
Therefore connect_to_db() is being defined twice. Use require_once instead to prevent this:
require_once __DIR__.'/dbconnect.php'
http://php.net/manual/en/function.require-once.php
I'm working on my own SignUp class but it seems I have a problem with the PDO calls
The browser returns this to me:
Fatal error: Call to a member function query() on a non-object
I have my database configuration in a file included then on the main page. It's as follows:
<?
$dsn = 'mysql:dbname=magazin-online;host=localhost;';
$username = 'root';
$password = '';
try{
$pdo = new PDO($dsn, $username, $password);
}catch(PDOException $e){
echo 'Connection failed!: '.$e->getMessage();
}
An the line in the SignUp class causing the error is this:
$pdo->query("insert into ... () ... values ());
Now, I don't make any db connection in my SignUp class because I already included the file resposible for it.
How can I get rid of that error?
try using exec instead of query:
$pdo->exec("insert into ... () ... values ());
You are catching the exception generated by the new PDO, and then continue execution.
By doing it this way, you have to check that the class exists, so change:
if( $pdo)
$pdo->query("insert into ... () ... values ());
But .. a better way is not to continue execution after a critical error like this.
So better change the connection like this:
$dsn = 'mysql:dbname=magazin-online;host=localhost;';
$username = 'root';
$password = '';
try{
$pdo = new PDO($dsn, $username, $password);
}catch(PDOException $e){
echo 'Connection failed!: '.$e->getMessage();
die;
}
If I understand correctly, $pdo is a global variable. If you are calling $pdo->query inside a function, you either have to pass the $pdo connection as a parameter or declare it as global
global $pdo;
in the beginning of the member function.