This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed 5 years ago.
I'm currently doing a populating/editing my DB using PHP on a webpage I'm going to build. I'm relatively new to PHP so please excuse my "greenhorn" knowledge. My DB connection works, however, I don't understand why my function "displaySQL" and then counting the quantity as an array is not generating anything on my webpage. There's no number displayed on the screen, I was going to have that value put inside an HTML table afterwards. My DB settings are also established for the parameter part (host, username, password). Thanks for any help.
class User{
var $conn;
function __construct($hostname,$username,$password){
try{
$conn = new PDO("mysql:host=$hostname;dbname=pjj5",
$username, $password);
echo "Connected successfully <br>";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
}
//display all users information
function displaySQL(){
$sql = "SELECT * FROM accounts";
$q = $conn->prepare($sql);
$q->execute();
$results = $q->fetchAll();
return $results;
}
$db = new User($hostname,$username,$password);
$res = $db->displaySQL();
echo count($res);
To access a variable of an object within the object you need to use the syntax $this->.
This line:
$conn = new PDO("mysql:host=$hostname;dbname=pjj5",
$username, $password);
and this line
$q = $conn->prepare($sql);
should have $this->conn instead of $conn. In the first function you create the connection to a new $conn variable that is local in scope to the function only, which gets discarded after the object is constructed. For the function displaySQL() $conn is undefined.
Related
This question already has answers here:
Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
(3 answers)
Closed 2 years ago.
I am trying to create a PHP function to update the SQL table to keep from reusing code over and over. However, whenever I run the function, I always get 'SQL database error.' The odd part about this is I do not get any type of error whenever I use copy/paste this snippet of code and put it by itself, not as a function. What is wrong? Why is it behaving this way?
$servername = "localhost";
$dBUsername = "username";
$dBPassword = "password";
$dBName = "databasename";
$connection = mysqli_connect($servername, $dBUsername, $dBPassword, $dBName);
function updateSQL ($table, $row, $value, $where, $arg) {
$SQL = '
UPDATE `".$table."`
SET `".$row."`=?
WHERE `".$where."`=?';
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $SQL)) {return "SQL database error."; exit();}
else {
mysqli_stmt_bind_param($stmt, "ss", $value, $arg);
if (mysqli_stmt_execute($stmt)) {return "success";}
else {return mysqli_error($connection);}
}
}
The $connection is not set in this scope (unless you're using it as a global variable, which we can't see in the code and it would be a bad practice anyway).
If the updateSQL() is a method of a object, you can set $this->connection property in the constructor (or any other suitable place) and then access it in the updateSQL() method.
Otherwise, pass it as an argument to the updateSQL() function the same way as you're passing the $table, $row and other arguments.
This question already has answers here:
pdo - Call to a member function prepare() on a non-object [duplicate]
(8 answers)
Closed 6 years ago.
I'm writing a function to check for records in my database before executing anything, and i'm getting the error Call to a member function prepare() which i don't quite understand. I've been struggeling for quite some time now, and i'd really appriciate some help
The problem should be with the prepare() in line 19
<?php
$dsn = "xxx"; // Database Source Name
$username="xxx"; // User with acress to database. Root is MySQL admin.
$password="xxx"; //The user password.
try {
$conn = new PDO($dsn, $username, $password);
$conn ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "Connection failed: ".$e->getMessage();
}
//------------------------ Does the category already exist? -------------------------
function checkuser($fbid,$fbfname,$fblname,$femail) {
$sql="SELECT COUNT(*) AS subjectcount FROM Users WHERE Fuid=:Fuid";
try {
$stmt = $conn->prepare($sql);
$stmt->bindValue(":Fuid",$_SESSION['FBID'], PDO::PARAM_INT);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$subjectcount=$row["subjectcount"];
} catch (PDOException $e) {
echo "Server Error - try again!".$e->getMessage();
}
//------------------------ If it dosn't, insert it -------------------------
if ($subjectcount==0) {
And i'm having a hard time debugging since i dont quite understand the cause of this error.
I updated my code to
<?php
$dsn = "xxx"; // Database Source Name
$username="xxx"; // User with acress to database. Root is MySQL admin.
$password="xxx"; //The user password.
try {
$conn = new PDO($dsn, $username, $password);
$conn ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "Connection failed: ".$e->getMessage();
}
//------------------------ Does the category already exist? -------------------------
function checkuser($fbid,$fbfname,$fblname,$femail) {
global $conn;
$sql="SELECT COUNT(*) AS subjectcount FROM Users WHERE Fuid=:Fuid";
try {
$stmt = $conn->prepare($sql);
$stmt->bindValue(":Fuid",$_SESSION['FBID'], PDO::PARAM_INT);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$subjectcount=$row["subjectcount"];
} catch (PDOException $e) {
echo "Server Error - try again!".$e->getMessage();
exit;
}
//------------------------ If it dosn't, insert it -------------------------
if ($subjectcount==0) {
I guess the full error message is:
Fatal error: Call to a member function prepare() on a non-object
Right?
You are calling the member function (= function which is a member of a class instance) prepare of the variable $conn which is not declared in the scope of your checkuser function, it's declared outside (in global scope)!
To "import" it into your function so you can access it, put this line at the top of your function:
global $conn;
Also, it looks like you don't have full error reporting enabled, otherwise you would have seen this error before the fatal one, giving you another clue:
Notice: Undefined variable: conn
(By the way, you should exit; after outputing the DB error message in your catch block - otherwise you will print the error but continue to the rest, with a nonexisting DB connection!)
I'm in the process of upgrading from mysql to mysqli.
All my mysql code was procedural, and I'd now like to convert to OOP, as most mysqli examples online are in OOP.
The problem I'm having is that, with mysql, once I had set up a connection, I never had to inject that connection into any functions as arguments for mysql to be accessible in the function.
Here is my old connection code:
$location = "localhost";
$user = "rogerRamjet";
$pass = "bestPassInTheWorld";
$dbName = "myDBName";
$link = mysql_connect($location, $user, $pass);
if (!$link) {
die("Could not connect to the database.");
}
mysql_select_db("$dbName") or die ("no database");
And an example function that has access to the mysql connection, without $link needing to be injected into the function:
function getUser($data)
{
$data=mysql_real_escape_string($data);
$error = array('status'=>false,'userID'=>-1);
$query = "SELECT `user_id`, `user_email` FROM `myTable` WHERE `data`='$data'";
if ($result = mysql_query($query))
{
$row = mysql_fetch_array($result, MYSQL_ASSOC);
if ($row['user_id']!="")
{
return array( 'status'=>true, 'userID'=>$row['user_id'], 'email'=>$row['user_email'] );
}
else return $error;
}
else return $error;
}
And here's my new mysqli connection:
$mysqli=new MySQLi($location, $user, $pass, $dbName);
So, to upgrade the first line in the above function, I'd need:
$data = $mysqli->real_escape_string($data);
But that throws the error:
Undefined variable: mysqli
Does this mean that for any function needing access to $mysqli, I need to inject $mysqli as an argument into it, or is there a way for it to be accessible the way mysql is without injection?
I know I need to move to prepared statements, but this is just so I can get my head around mysqli basics.
Making the variable global is bad practice. The singleton pattern solves the issue of needing to share one instance of an object throughout an application lifecycle. Consider using a Singleton.
The crude solution would be global $mysqli; as first line of your function. But as hsan wrote, read about PHP variable scope
This question already has an answer here:
How to use PDO connection in other classes?
(1 answer)
Closed 2 years ago.
Hello i am new to PDO with MYSQL, here are my two files
1) index.php
require_once 'prd.php';
try{
$db = new PDO ('mysql:host=xxxx;dbname=xxx;charset=utf8', 'xxx', 'xxxx');
echo 'connectd';
}catch(PDOException $conError){
echo 'failed to connect DB' . $conError->getMessage ();
}
$conn = new prdinfo();
$conn->con($db);
2) product.php
class prdinfo{function con($db){
try{
foreach($db->query("select * from products where vendor_id = 2" ) as $row){
$prod_id = $row ['product_id'];
echo '<br/>' . $prod_id;
}
}catch(PDOException $ex){
echo 'an error occured' . $ex->getMessage();
}
}
}
my problem is here i can pass the connection object to every file, but i have so many files to use database queries, so i need to pass the $bd to all the files. this is getting burden on the code. so is there any way to connect the database with PDO.
Thanks
pdo.php, taken from here. People often overlook many important connection options, so I had to write a dedicated article that explains how to connect with PDO properly
product.php
<?php
class prdinfo
{
function __construct($db)
{
$this->db = $db;
}
function getVendor($vendor)
{
$sql = "select * from products where vendor_id = ?";
$stm = $this->db->prepare($sql);
$stm->execute(array($vendor));
return $stm->fetchAll();
}
}
index.php
<?php
require 'pdo.php';
require 'product.php';
$info = new prdinfo($pdo);
$vendor = $info->getVendor(2);
foreach ($vendor as $row)
{
echo $row['product_id'];
}
It would be also a good idea to implement class autoloading instead of manually calling require.
The simplest way of doing it is to do the database connectivity in a separate file like "database.php and then you can include this file on every new page you are creating...eg if you are creating a page like "dothis.php". then at the top of your dothis.php page write a statement include_once ('/path/to/your/file/database.php');
then you can use your $db object in the whole file wherever you want.
What you can do is to create a PHP file, let's say 'pdoconn.php'. In that file, prepare that $db object. Finally, for each of your PHP files, just include pdoconn.php at first. So, while your PHP files are being loaded, they will firstly connect to MySQL and give you the $db object.
I realize this is probably super simple but i just started taking peoples advice and im converting a small program from mysql to PDO as an attempt to learn and switch to PDO.
The script is a script that shows you how to build a shopping cart, so keep in mind its focused on a learning audience like myself. Anyway i converted the old script here:
function db_connect()
{
$connection = mysql_pconnect('localhost', 'database_1', 'password');
if(!$connection)
{
return false;
}
if(!mysql_select_db('database_1'))
{
return false;
}
return $connection;
}
to this which does connect fine:
function db_connect() {
//Hostname
$hostname = 'xxx.com';
//username
$username = 'xxx';
//password
$password = 'xxx';
try {
$connection = new PDO("mysql:host=$hostname;dbname=database_1", $username, $password);
}
catch(PDOException $e){
echo $e->getMessage();
}
}
Now in other parts of the script before accessing the database it does this:
$connection = db_connect();
Now i have 2 questions. First is to help me understand better what is going on.
I understand in the original mysql function we connect to the database, if the connection is unsuccessful or the database doesnt exist it returns false. If it does connect to the database then it returns true.
With that i mind i dont understand this:
$connection = db_connect();
Isnt that just assigning true or false to the $connection variable, if so then whats going on in this part of the code.
$price = 0.00;
$connection = db_connect();
if (is_array($cart))
{
foreach($cart as $id => $qty)
{
$query = "SELECT price
FROM products
WHERE products.id = '$id' ";
$result = mysql_query($query);
if($result)
{
$item_price = mysql_result($result, 0, 'price');
$price += $item_price * $qty;
}
}
}
Instead couldn't i just create an include file with the PDO connection and no function and include that at the top of each page i run scripts on. I just don't understand where the $connection = db_connect comes in.
So the 2nd question if my above suggestion is not the answer is how do i return a boolean value from the connection function to return true or false (If i even need to)
There is one essential difference between old mysql and PDO: both these libraries require a resource variable to connect with. If you take a look at mysql_query() function definition, you will notice the second parameter, represents such a resource.
$connection variable returned by your old function by no means contain boolean value but such a resource variable. Which can be used in every mysql_query call.
But while for mysql ext this resource parameter being optional, and used automatically when not set, with PDO you have to address this resource variable explicitly. Means you cannot just call any PDO function anywhere in the code, but only as a method of existing PDO object. Means you have to make this variable available wherever you need PDO.
Thus, you need not a boolean but PDO object.
Here is the right code for the function:
function db_connect()
{
$dsn = "mysql:host=localhost;dbname=test;charset=utf8";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
return new PDO($dsn,'root','', $opt);
}
now you can use it this way
$pdo = db_connect();
but note again - unlike with mysql_query(), you have to always use this $pdo variable for your queries.
Further reading is PDO tag wiki
As you guessed from the context, db_connect() is supposed to return the connection object. Your converted version doesn't return anything, which is a problem.
With the mysql module, you can run queries without using the connection object - this is not the case with PDO. You'll need to use the connection object to run any queries -
$result = $connection->query('SELECT * FROM foo');
First off, let me congratulate you for making the effort to learn PDO over mysql_*. You're ahead of the curve!
Now, a few things to understand:
PDO is OO, meaning the connection to the database is represented by a PDO Object.
Your db_connect() function should return the object that gets created.
Passing in the parameters required by PDO will give you more flexibility!
So what we have is:
function db_connect($dsn, $username, $password)
{
$conn = new PDO($dsn, $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //This makes sure that PDO will throw PDOException objects on errors, which makes it much easier enter code hereto debug.
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //This disables emulated prepared statements by PHP, and switches to *true* prepared statements in MySQL.
return $conn; //Returns the connection object so that it may be used from the outside.
}
Now, you may have noticed we aren't checking for PDOExceptions inside of the function! That's because you can't handle the error from inside of the function correctly (becuase you don't know what you would want to do? Would you terminate the page? Redirect to an error message?). So you can only know it when you call the function.
So usage:
try {
$connection = db_connect("mysql:host=$hostname;dbname=database", "user", "pass");
}
catch (PDOException $e) {
echo "Database error! " . $e->getMessage();
}
Further Reading!
The PDO Manual entry - is super easy and super useful. I recommend you read all of it.