This question already has answers here:
What does the variable $this mean in PHP?
(11 answers)
Closed 4 years ago.
I was always taught and used $con->prepare for prepared statements. However, this article two answers posted people where using $con->sqli->prepare. I also saw a few others using it in other articles.
Is this something to be concerned with?
What is the difference?
Usually some people make database connection class with constructor of connection. It means that when you initialize the object of that class, the constructor is executed automatically.
For example here is Database class
<?php
class db
{
public $conn;
public function __construct()
{
$this->conn=mysqli_connect("localhost","root","","prepared");//A constructor is a function that is executed after the object has been initialized (its memory allocated, instance properties copied etc.). Its purpose is to put the object in a valid state.
if($this->conn)
{
echo "";
}
else{
echo $this->conn->error;
}
}
}
$db = new db();
?>
Child class
include("db.php");
class childclass extends db
{
public function database_query()//here you don't need to put $conn in parameters
{
$sql = "SELECT * FROM table";
$result = $this->conn->query($sql);//Here you can see how we can call conn from db class
print_r($result);
}
}
I hope you got my point.
Related
This question already has answers here:
Is it possible to use mysqli_fetch_object with a prepared statement
(3 answers)
Closed 6 years ago.
So, I have the following function:
private function getUserData($user_nickname)
{
if ($this->databaseConnection()) {
$stmt1=$this->dbh->prepare('SELECT * FROM users WHERE nickname = ?');
$stmt1->bind_param('s', $user_nickname);
$stmt1->execute();
return $stmt1->fetch_object();
}
else {
return false;
}
}
And I get the following error: Fatal error: Uncaught Error: Call to undefined method mysqli_stmt::fetch_object()
I did a little research and I didn't find any fetch object in mysqli_stmt
http://php.net/manual/en/class.mysqli-stmt.php
Does it means that if I use prepared statements, I can't use result as an object? I really want it to work as an object.
P.S. I use mysqli.
Mysqli is not a very usable API.
You can try to use get_result() but it could be unavailable on your system.
Let me suggest you to use PDO instead of mysqli:
private function getUserData($user_nickname)
{
$stmt = $this->dbh->prepare('SELECT * FROM users WHERE nickname = ?');
$stmt->execute([$user_nickname]);
return $stmt->fetch(PDO::FETCH_OBJ);
}
Among other benefits over mysqli, PDO can return not only an anonymous stdObject but can create an instance of an existing class, passing parameters to constructor. Say, if you have a User class, you may write
private function getUserData($user_nickname)
{
$stmt = $this->dbh->prepare('SELECT * FROM users WHERE nickname = ?');
$stmt->execute([$user_nickname]);
return $stmt->fetchObject('User');
}
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 9 years ago.
Is it possible to bind a table name?
I want to make a class to read the columns from a tables and, depending on field type, generate the form inputs for me. When I do $form = new form("users");, the constructor is supposed to start with getting the field names from the table with the following code:
class form{
public function __construct($table, $skip = array("id")){
$pdo = new PDO('mysql:host=localhost;dbname=site;',USER,PASS);
$query = $pdo->prepare("DESCRIBE :table");
$query->bindValue(':table', $table, PDO::PARAM_STR, strlen($table));
$query->execute();
while($field = $query->fetch(PDO::FETCH_NUM)){
var_dump($field);
echo "<br /><br />";
}
unset($pdo);
}
}
This works just fine when I specify "users" instead of ":table" in the prepare statement, but the bind it's working, and I'm pretty sure it's because it's trying to bind a table name. Also, this needs to be binded because I'd like to have the ability to pass my table names through $_GET and the such.
Is it possible to bind a table name?
No.
You have to whitelist table names. I doubt you want to let a user to browse any table from your database.
Given you are using a class, it will be no-brainer to add a table name as a property. It will be simple, elegant and safe. Create an abstract parent class first
abstract class abstractTable {
private $table;
private $db;
public function __construct($pdo){
$this->db = $pdo;
}
public function describe() {
return $db->query("DESCRIBE `$this->table`")->fetchAll();
}
}
Then create a specific class for your table
class someTable extends abstractTable {
private $table = 'sometable';
}
and so you will be able to get the required list of columns
$pdo = new PDO(...);
$table = new someTable($pdo);
$fields = $table->describe();
simple, concise, powerful, safe.
There is a PDO wrapper class at - http://www.phpclasses.org/package/5997-PHP-Database-access-abstraction-layer.html that lets you do this (though I am new to PDO so maybe it isnt using prepared statements)
His suggested usage is:
$db = new DatabaseConnection('someMysqlServer', 'user', 'pass', 'database');
$result = $db->exec($db->filterForSql('SELECT * FROM '.$tableName.';'));
I would interested if others think this is a 'safe' way of using PDO or not.
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 9 years ago.
Is it possible to bind a table name?
I want to make a class to read the columns from a tables and, depending on field type, generate the form inputs for me. When I do $form = new form("users");, the constructor is supposed to start with getting the field names from the table with the following code:
class form{
public function __construct($table, $skip = array("id")){
$pdo = new PDO('mysql:host=localhost;dbname=site;',USER,PASS);
$query = $pdo->prepare("DESCRIBE :table");
$query->bindValue(':table', $table, PDO::PARAM_STR, strlen($table));
$query->execute();
while($field = $query->fetch(PDO::FETCH_NUM)){
var_dump($field);
echo "<br /><br />";
}
unset($pdo);
}
}
This works just fine when I specify "users" instead of ":table" in the prepare statement, but the bind it's working, and I'm pretty sure it's because it's trying to bind a table name. Also, this needs to be binded because I'd like to have the ability to pass my table names through $_GET and the such.
Is it possible to bind a table name?
No.
You have to whitelist table names. I doubt you want to let a user to browse any table from your database.
Given you are using a class, it will be no-brainer to add a table name as a property. It will be simple, elegant and safe. Create an abstract parent class first
abstract class abstractTable {
private $table;
private $db;
public function __construct($pdo){
$this->db = $pdo;
}
public function describe() {
return $db->query("DESCRIBE `$this->table`")->fetchAll();
}
}
Then create a specific class for your table
class someTable extends abstractTable {
private $table = 'sometable';
}
and so you will be able to get the required list of columns
$pdo = new PDO(...);
$table = new someTable($pdo);
$fields = $table->describe();
simple, concise, powerful, safe.
There is a PDO wrapper class at - http://www.phpclasses.org/package/5997-PHP-Database-access-abstraction-layer.html that lets you do this (though I am new to PDO so maybe it isnt using prepared statements)
His suggested usage is:
$db = new DatabaseConnection('someMysqlServer', 'user', 'pass', 'database');
$result = $db->exec($db->filterForSql('SELECT * FROM '.$tableName.';'));
I would interested if others think this is a 'safe' way of using PDO or not.
I have a simple core class that is being used for core functions to a small web app. I have defined some constants in the class - which has mostly static functions - and I am wanting to set / edit these constants outside of the class, example:
class core{
const connection = '';
public static function someSqlScript(){
$sql = "SELECT * FROM sometable WHERE someconditions";
$exec = mysqli_query(self::connection, $sql);
}
}
Now, I want to be able to set the connection constant so that it references a mysql connection object, which (by means of another script), has already been assigned to the variable $con, so essentially I am after something like this:
core::connection = $con; //send connection for use in class
core::someSqlScript(); //should not perform the MySQL query using conneciton $con as above
Any help is greatly appreciated, I am used to using non static functions and variables within classes, but the static functions with constants has got me.
Thanks to all.
The meaning of constant is, that you can't change it. You want a static variable:
class core{
public static $connection = '';
public static function someSqlScript(){
$sql = "SELECT * FROM sometable WHERE someconditions";
$exec = mysqli_query(self::$connection, $sql);
}
}
core::$connection = $con;
core::someSqlScript();
Note the public static $connection instead of const connection and self::$connection instead of self::connection (also core::$connection instead of core::connection).
The idea of constants is, that they cannot be changed after their definition.
I just started switching my project form the mysql to PDO. In my project a new PDO Object is created more or less right a the beginning of the programm.
$dbh_pdo = new PDO("mysql:host=$db_url;dbname=$db_database_name", $db_user, $db_password);
Now I would like to use this handler (is that the correct name?) in some functions and classes. Is there a way to make objects global just like variables or am I trying something unspeakably stupid, because I couldn't find anything when searching the web ...
Yes, you can make objects global just like any other variable:
$pdo = new PDO('something');
function foo() {
global $pdo;
$pdo->prepare('...');
}
You may also want to check out the Singleton pattern, which basically is a global, OO-style.
That being said, I'd recommend you not to use globals. They can be a pain when debugging and testing, because it's hard to tell who modified/used/accessed it because everything can. Their usage is generally considered a bad practice. Consider reviewing your design a little bit.
I don't know how your application looks like, but say you were doing this:
class TableCreator {
public function createFromId($id) {
global $pdo;
$stmt = $pdo->prepare('SELECT * FROM mytable WHERE id = ?');
$stmt->execute(array($id));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
// do stuff
}
}
}
You should do that instead:
class TableCreator {
protected $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function createFromId($id) {
$stmt = $this->pdo->prepare('SELECT * FROM mytable WHERE id = ?');
$stmt->execute(array($id));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
// do stuff
}
}
}
Since the TableCreator class here requires a PDO object to work properly, it makes perfect sense to pass one to it when creating an instance.
You'll use $GLOBALS['dbh_pdo'] instead of $dbh_pdo inside any functions. Or you can use the global keyword, and use $dbh_pdo (i.e. global $dbh_pdo).
You could also try using a Singleton to pass back a PDO object to you. That way you only ever have one PDO object (and one database connection) in any request which saves on memory/server resources.