Properties cannot be used outside of try catch blocks - php

I am trying to use properties inside try catch blocks.
The try catch blocks are inside classes.
I want to extend a specific class, making it the subclass of the class which handles exceptions.
The problem is, that when I try to use those variables from the subclass, it always says undefined. I have to delete both of classes in order to catch the properties. After reading some other answers here by adding a return statement (I added return 1) outside, inside of the try catch block, it doesn't seem to work and it always says undefined variable.
Any help?
The language is php
The source code without classes works perfect:
try
{
//$pdo variable to insert PDO object information
$pdo = new PDO('mysql:host=localhost;dbname=studenti', 'root', '');
//Set php to catch exceptions
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Set UTF-8 for character encodings
$pdo->exec('SET NAMES "utf8"');
}
//Catch error if unable to connect
catch(PDOException $e)
{
//error variable
$error = 'Unable to connect with database. ' . $e->getMessage();
//include file once and show on screen error message
include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/error.inc.php';
//Exit and don't process further
exit();
}
//Another Exception handling
try
{
//Select statement
$sql = 'SELECT * FROM dega';
$select = $pdo->query($sql);
}
catch(PDOException $e)
{
//error variable
$error = 'Unable to select table. ' . $e->getMessage();
//include file once and show on screen error message
include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/error.inc.php';
//Exit and don't process further
exit();
}
The source code with classes doesn't work:
<?php
//PDO class, connection with MySQL database
class Connect
{
function connection()
{
$pdo = null;
try
{
//$pdo variable to insert PDO object information
$pdo = new PDO('mysql:host=localhost;dbname=studenti', 'root', '');
//Set php to catch exceptions
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Set UTF-8 for character encodings
$pdo->exec('SET NAMES "utf8"');
}
//Catch error if unable to connect
catch(PDOException $e)
{
//error variable
$error = 'Unable to connect with database. ' . $e->getMessage();
//include file once and show on screen error message
include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/error.inc.php';
//Exit and don't process further
exit();
}
}
}
class Select extends Connect
{
function selection()
{
//Another Exception handling
try
{
//Select statement
$sql = 'SELECT * FROM dega';
$select = $pdo->query($sql);
}
catch(PDOException $e)
{
//error variable
$error = 'Unable to select table. ' . $e->getMessage();
//include file once and show on screen error message
include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/error.inc.php';
//Exit and don't process further
exit();
}
}
}
//Output if successful
$error = 'Database connection established.';
include $_SERVER['DOCUMENT_ROOT'] . '/inc/error.inc.php';
?>

You have no subclass. Object Inheritance
You have no properties. Properties
Read about Classes and Objects.
class Connect
{
protected $pdo = null;
public function connection()
{
$pdo = null;
try
{
$this->pdo = new PDO('mysql:host=localhost;dbname=studenti', 'root', '');
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->exec('SET NAMES "utf8"');
} catch (PDOException $e)
{
$error = 'Unable to connect with database. ' . $e->getMessage();
include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/error.inc.php';
exit();
}
}
}
class Select extends Connect
{
function selection()
{
try
{
$sql = 'SELECT * FROM dega';
$select = $this->pdo->query($sql);
} catch (PDOException $e)
{
$error = 'Unable to select table. ' . $e->getMessage();
include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/error.inc.php';
exit();
}
}
}

Put $pdo just before connection():
class Connect
{
protected $pdo = null; // or var $pdo = null;
function connection()
{
...
Inside the function it's a local variable not a class level property.
EDIT:
PHP requires $this-><class-variable> to access class properties inside functions. (Check out #Sectus's answer below.) Just using $pdo is creating a local variable on the fly (in both the methods) but gives an error in only selection() because that's where query() is being invoked without initializing a PDO() object first.

Related

Class not found on AWS Elastic beanstalk environment

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

PDOException not being caught

I'm working on a simple login with mysql using pdo. Everything works fine so now I'm focusing on the error handling. But there's a problem. In my dbconfig I voluntarily saved the wrong psw/email/dbname to create an error.
<?php
session_start();
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'Captive');
define('DB_PASSWORD', 'arancione');
define('DB_DATABASE', 'geochimie');
function get_db() {
$dbhost=DB_SERVER;
$dbuser=DB_USERNAME;
$dbpass=DB_PASSWORD;
$dbname=DB_DATABASE;
try {
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->exec("set names utf8");
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
catch (PDOException $e) {
header("../pages/errore.php?errore=dbconfig");
}
}
?>
However, no error can be caught so when I prepare a statement using the db connection returned by get_db() I get this:
Uncaught Error: Call to a member function prepare() on null
Here is the php script where I prepare the stmt:
<?php
class Admin {
public function userLogin( $email,$password)
{
try{
$db = get_db();
$stmt = $db->prepare('SELECT id FROM admin WHERE email=:email AND psw=:hash_password');
$stmt->bindParam("email", $email,PDO::PARAM_STR) ;
$stmt->bindParam("hash_password", $password,PDO::PARAM_STR) ;
$stmt->execute();
$count=$stmt->rowCount();
$data=$stmt->fetch(PDO::FETCH_OBJ);
$db = null;
if($count)
{
$_SESSION['uid']=$data->id;
return true;
}
else
{
return false;
}
}
catch(PDOException $e) {
header("Location: ../pages/errore.php?errore=db");
}
}
}
?>
As you can see there is another try-catch but It doesn't work at the same way. Many thanks for your attention!
Ok guys, It seems that I needed to add die() or exit() after the header in the catch blocks. Now I can handle the errors properly.

Using Exceptions to control application flow

I am currently writing a web app in PHP and have decided to use exceptions (duh!).
I could not find an answer to whether putting try and catch blocks in all functions would be considered bad code.
I am currently using Exceptions to handle Database errors (Application errors are handled via a simple function which just adds them to an array and then they are displayed to the user). The try blocks are placed on all functions which require a database connection.
The code in question is:
public function db_conn_verify()
{
if(!isset($this->_mysqli)){
throw new Exception("Network Error: Database connection could not be established.");
} else {
return Null;
}
}
And an example function using this code:
public function get_users() {
try {
$this->db_conn_verify();
//Rest of function code
return True;
} Catch(Exception $e) {
Core::system_error('function get_users()', $e->getMessage());
return False;
}
}
Also would it be better to extend the Exception class and then use that new Exception class to handle application errors?
Thanks
I suggest to you to use something like this:
public function get_users() {
try {
if( !isset($this->_mysqli) ) {
throw new Exception("Network Error: Database connection could not be established.");
}
//Rest of function code
} Catch(Exception $e) {
Core::system_error('function get_users()', $e->getMessage());
}
}
I prefer to use my exends of Exception, but is the same. For exdending exception you can see the PHP documentation to Example #5
EDIT: For an immediate use of try-catch on database connection error you can try this:
try{
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
throw new Exception("Network Error: Database connection could not be established.");
}
} Catch(Exception $e) {
Core::system_error('function get_users()', $e->getMessage());
}

php cant load internal PDO class

private function _connect(){
try {
$this->con = new PDO(''.$this->dbdriver.':host='.$this->dbhost.';dbname='.$this->dbname.'', $this->dbuser, $this->dbpass);
$this->con->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
return TRUE;
} catch (PDOException $e){
$reg = registry::_getInstance();
$reg->offsetSet('R_errors', $reg->offsetGet('R_errors').'</br>'.$e->getMessage());return false;
}
}
I am using the above code to connect to the database but am getting the following errors:
Fatal error: spl_autoload(): Class PDO could not be loaded in /home/tahidihomes/public_html/lib/core/pdo_mysql.core.php on line 72
What might be the problem?
Retry after PDO installation. If you get same error try again with the below code in top of index page
spl_autoload_extensions('.php, .class.php');
spl_autoload_register();

Check username exists using PHP and PDO?

I have a db.php file that has the following in it:
// db.php file
// creates connection to database
// DATABASE CONNECTION FUNCTION
function sql_con(){
try{
$dbh = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
// log error to file and display friendly error to user
ExceptionErrorHandler($e);
exit;
}
}
I have a signup page and i want to check if username already exists, so i call my sql_con(); function beforehand to connect to database then do the below query
// connect to database
sql_con();
$stmt = $dbh->prepare("SELECT `user_login` FROM `users` WHERE `user_login` = ? LIMIT 1");
$stmt->execute(array($username));
if ( $stmt->rowCount() > 0 ) {
$error[] = 'Username already taken';
}
I'm very new to PDO and with the above i get the following errors:
Notice: Undefined variable: dbh in C:\wamp\www\signup.php on line 64
Fatal error: Call to a member function prepare() on a non-object in
C:\wamp\www\signup.php on line 64
Probably something very silly and I seem to confuse myself with PDO as I'm at the beginner stages. Could anyone tell me what I am doing wrong? Also I am not sure if this is the correct way as I'm new to PDO so if there's a more efficient way to do the username query check then please let me know.
This is because the $dbh object is limited to inside the try catch block and your sql_con() function due to scope.
The correct solution would be to remove the try catch block, and return the $dbh variable at the end of the sql_con() function.
Then:
try {
$dbh = sql_con();
$stmt = $dbh->prepare("SELECT `user_login` FROM `users` WHERE `user_login` = ? LIMIT 1");
$stmt->execute(array($username));
if ( $stmt->rowCount() > 0 ) {
$error[] = 'Username already taken';
}
}
catch (PDOException $e) {
//Do stuff with $e
}
The $dbh variable is destroyed once the function is done executing.
You could try returning the handle:
function sql_con() {
// your connection code
return $dbh;
}
Then in your signup page:
$dbh = sql_con();
Depending on your needs, a better alternative would be to employ a DI container.
You are defining pdo in function an ist not visible out it.
function sql_con(){
try{
$dbh = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh; //this
} catch (PDOException $e) {
// log error to file and display friendly error to user
ExceptionErrorHandler($e);
exit;
}
}
$dbh = sql_con();
It will be better if you create a class for pdo abstraction.
$dbh = DB::getInstance();

Categories