Select PHP PDO best way to make - php

I have a question on how to draw a connection to a select box that is inside a function.
I call this way:
Function MySQL:
mysql.php
function conectar() {
try {
$dbh = new PDO("mysql:host=localhost;dbname=adm-new", 'root', '');
} catch (PDOException $dbe) {
echo $dbe->getMessage();
}
return $dbh;
}
$conn = conectar();
Function select:
menu.php
function z_menu_todos() {
global $conn;
$z_menu = "SELECT *
FROM z_menu
ORDER BY posicao ASC";
return $conn->prepare($z_menu);
}
I did not want to call the variable global $conn.
What would be the best way to do?

I would create a DatabaseFactory class which would serve for creating database connection, like this:
ConnectionFactory.php
class ConnectionFactory {
private $_connection;
public function __construct($dbName, $dbUser, $dbPassword, $dbHost = 'localhost'){
try {
$this->_connection = new PDO("mysql:host=$dbHost;dbname=$dbName", $dbUser, $dbPassword);
$this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e){
throw new DatabaseFactoryException('Could not create connection:' . $e->getMessage());
}
}
public function getConnection(){
return $this->_connection;
}
}
After that I would create MenuRepository class which would server for executing queries associated with Menu, like this:
MenuRepository.php
class MenuRepository {
private $_connection;
public function __construct(PDO $connection){
$this->_connection = $connection;
}
public function getMenus(){
$stmt = $this->_connection->prepare("SELECT * FROM z_menu ORDER BY posicao ASC");
$stmt->execute();
return $stmt->fetchAll();
}
}
I would create configuration in separate file, like this:
config.php
define('DB_NAME', 'adm-new');
define('DB_USER', 'root');
define('DB_PASS', '');
After that I would use:
index.php
require __DIR__ . '/config.php';
require __DIR__ . '/ConnectionFactory.php';
require __DIR__ . '/MenuRepository.php';
$connectionFactory = new ConnectionFactory(DB_NAME, DB_USER, DB_PASS);
$connection = $connectionFactory->getConnection();
$menuRepository = new MenuRepository($connection);
$menus = $menuRepository->getMenus();

class Database
{
protected $conn;
public function __construct()
{
try {
$this->conn = new PDO("mysql:host=localhost;dbname=adm-new", 'root', '');
} catch (PDOException $dbe) {
echo $this->conn->getMessage();
}
}
public function z_menu_todos()
{
$z_menu = "SELECT *
FROM z_menu
ORDER BY posicao ASC";
return $this->conn->prepare($z_menu);
}
}
Usage
$database = new Database();
$stmt = $database->z_menu_todos();
Modify this as you require, this is a very basic example of how to do this, do not just copy and paste it.

In this case, you should avoid using global variables, because you can easily pass the connection to method as method argument, like this:
function conectar() {
try {
$dbh = new PDO("mysql:host=localhost;dbname=adm-new", 'root', '');
} catch (PDOException $dbe) {
echo $dbe->getMessage();
}
return $dbh;
}
$conn = conectar();
function z_menu_todos($conn) {
$z_menu = "SELECT * FROM z_menu ORDER BY posicao ASC";
return $conn->prepare($z_menu);
}
However, it might be a good idea to create a separate class for managing your database connection and other stuff purely related to database and another class for executing SQL queries against your menu table.

Related

I will want to use my connection to my database as a function that I can use in my other pages

Here is the code I am currently running, including two functions connect_database and disconnect_database
function connect_database(){
try {
$bdd = new PDO('mysql:host=localhost;dbname=test1;charset=utf8', 'root', '');
} catch (Exception $e) {
die('Erreur : ' . $e->getMessage());
}
return $bdd;
};
function disconnect_database($request){
$request->closeCursor();
};
create a database class lets say
class Database {
public function connect(){
// connect
return $connection;
}
public function close(){
// disconnect
}
}
then include it to the module you want to connect to database.
$database = new Database();
$connection = $database->connect();
$database->close();

Class 'Db' not found

When I attempt to connect to my SQL database with my pdo_object.php file, my model.php returns this error:
Fatal error: Class 'Db' not found in /path/model.php on line 8
I made sure all of the permissions are correct and credentials are correct for all of my files. Here are the two files in question.
Not really sure what the issue is here so any help would be awesome.
pdo_object.php
<?php
$user = 'someusername';
$pass = 'somepassword';
$db_info='somehost';
try {
$db = new PDO($db_info, $user, $pass);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
and then model.php
<?php
include('pdo_object.php');
class Model{
public $db;
public function __construct(){
$this->db = Db::getDb();
}
public function getAllRecords($sql, $parameters = null){
$stm = $this->db->prepare($sql);
$stm->execute($parameters);
return $stm->fetchAll();
}
public function getOneRecord($sql, $parameters = null){
$stm = $this->db->prepare($sql);
$stm->execute($parameters);
return $stm->fetch();
}
}
?>
Where is class Db { //blah }? Nowhere. But you HAVE defined $db in the first file.
I also recommend dependency injection, rather than calling static class methods inside your class. Essentially, pass the $db in in the constructor:
public function __construct(PDO $db)
{
$this->db = $db;
}
And instantiate like so:
$model = new Model($db);
The Db class was not present in the pdo_object.php file, thus resulting in the index.php file throwing an error when referencing a non existing class.
class Db {
private static $db;
public static function getDb() {
if(!self::$db) {
try {
$dsn = 'somehost; dbname=somedbname';
self::$db = new PDO($dsn, 'username', 'password');
self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
} catch (PDOException $e) {
die('Connection error: ' . $e->getMessage());
}
}
return self::$db;
}
}

PHP PDO class use in different class (doesn't work)

I wanna get data on table and write a class. But this class doesn't work because pdo doesn't access. How can I get table data with this class?
$db = new PDO("mysql:host=localhost;dbname=xxx;charset=utf8", "xxx", "xxx");
class uye extends PDO{
var $id;
var $kadi;
function cek($id){
$query = $db->query("SELECT * FROM btc WHERE id='{$id}'", PDO::FETCH_ASSOC);
if ( $query->rowCount() ) {
foreach( $query as $row ){
$this->id=$row["id"];
$this->kadi=$row["kadi"];
}
}
}
}
$bilgiler=new uye;
$bilgiler->cek(1);
echo $bilgiler->kadi;
So I'm running this off of fetching all data as I dont know where you're getting $id from.
I generally break my code up into files and folders as I found this easier to work with and others to work on.
// database connection file (dbc.php)
class Database
{
private $host = "127.0.0.1";
private $db = "";
private $user = "";
private $password = "";
public $conn;
public function dbConnect()
{
$this->conn = null;
try
{
$this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db, $this->user, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $exception)
{
echo "Connection error: " . $exception->getMessage();
}
return $this->conn;
}
}
I then make a common file, this is where you can store all of your frequently used functions or your static functions
// Common file (common.php)
require_once('dbc.php');
class DBCommon
{
private $conn;
public function __construct()
{
$database = new Database();
$db = $database->dbConnect();
$this->conn = $db;
}
public function run($sql)
{
$stmt = $this->conn->prepare($sql);
return $stmt;
}
}
So to explain this a little more, you will see a function of run() this is just to save the tedious $this->conn->prepare on every query.. Now you can run $this->run()
The next would be your class file.. this is where your logic goes:
// your class file... (class.btc.php)
require_once "common.php";
class BTC extends DBCommon
{
public function getQuery()
{
$stmt = $this->run("SELECT * FROM `btc`");
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_OBJ))
{
$rows[] = $row;
}
return $rows;
}
}
Self explanatory..
And then your calling method.. Lets say index.php
// File you're calling your class from (index.php)
require_once "class.btc.php";
$fetch = new BTC();
$returnData = $fetch->getQuery();
foreach ($returnData as $data)
{
echo
"<p>$data->something</p>
<p>$data->somethingElse</p>";
}
It seems a little long winded I know, but the time you'll save overall will help!

Using function to create a connection

I'm trying to create a connection using function in my other php file. So I can access it in every php file. How can I call the function inside my class from another php file. What is the proper way creating instance of my function will I put it in the top of my file or inside my class? I try to run my system but the connection won't load.
connection.php
<?php
DEFINE ('host', 'localhost');
DEFINE ('username', 'root');
DEFINE ('password', '');
DEFINE ('database', 'librarysystem');
function getConnection()
{
$myDB = mysqli_connect(host,username,password,database);
if (!$myDB)
{
trigger_error ('Could not connect to MySQL: ' . mysqli_connect_error());
}
else
{
return $myDB;
}
}
?>
Another file where I'm gonna call my function or method.
loginCRUD.php
<?php
error_reporting(0);
require_once ('../connection/connection.php');
$myConnection = getConnection();
class loginCRUD
{
public function readLogin($dbusername,$dbpassword)
{
$statement = $myConnection->prepare("SELECT * FROM loginmodule WHERE loginUsername = ? AND loginPassword = ? LIMIT 1");
$statement->bind_param("ss", $dbusername, $dbpassword);
if($statement->execute())
{
$result = $statement->get_result();
if($result->num_rows)
{
$row = $result->fetch_assoc();
return $row;
}
else
{
return false;
}
}
else
{
return false;
}
}
}
(new loginCRUD)->readLogin($dbusername,$dbpassword);
?>
There can be at least two possible ways of passing $myConnection to your loginCRUD class.
First is to create $myConnection in a class itself:
class loginCRUD
{
protected $dbCon;
public function __construct()
{
$this->dbCon = getConnection();
}
public function readLogin($dbusername,$dbpassword)
{
$statement = $this->dbCon->prepare("YOUR SQL")
// other codes
}
}
(new loginCRUD)->readLogin($dbusername,$dbpassword);
Second is to pass $myConnection as an argument to your class constructor:
class loginCRUD
{
protected $dbCon;
public function __construct($myCon)
{
$this->dbCon = $myCon;
}
public function readLogin($dbusername,$dbpassword)
{
$statement = $this->dbCon->prepare("YOUR SQL")
// other codes
}
}
$myConnection = getConnection();
(new loginCRUD($myConnection))->readLogin($dbusername,$dbpassword);
The reason you are getting an error is due to your variable scope. In your loginCRUDclass you try to access a variable called myConnection, it fails to find it because the scope of the function is only that function. It doesn't know that you mean the global declared variable. A correct way of fixing this should be:
...
public function readLogin($dbusername,$dbpassword)
{
global $myConnection;
$statement = $myConnection->prepare("SELECT * FROM loginmodule WHERE loginUsername = ? AND loginPassword = ? LIMIT 1");
$statement->bind_param("ss", $dbusername, $dbpassword);
if($statement->execute())
{
...
For reference: Accessing variables and methods outside of class definitions

PHP OOP: Duplicate Code in a Class

I have a PHP class with two methods. One connects to a MySQL database for output, and the other connects to a MySQL database for input.
My question is, for both functions, I repeated the code for connecting to the database. What would be a better way to maybe have a third function in the class to connect to the DB and have the other two call the function to establish the connection, rather than repeat the code twice? I'm a PHP n00b trying to improve my OOP coding. Notice how I connected to the DB twice--using the exact same code:
class output_mysql {
var $db_name = 'database';
var $db_username = 'name';
var $db_password = 'mypassword';
function print_table_cell($tbl_name, $colm_name, $array_index_num) {
try {
$pdo = new PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
$error = 'Unable to connect to the database server.';
include 'output_mysql_error.php';
exit();
}
try {
$sql = "SELECT $colm_name FROM $tbl_name";
$result = $pdo->query($sql);
}
catch (PDOException $e) {
$error = 'Error fetching content: ' . $e->getMessage();
include 'output_mysql_error.php';
exit();
}
while ($row = $result->fetch()) {
$all_content[] = $row["$colm_name"];
}
echo $all_content[$array_index_num];
}
function update_content($tbl_name, $colm_name, $error_message_text, $id_num) {
try {
$pdo = new PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
$error = 'Unable to connect to the database server.';
include 'output_mysql_error.php';
exit();
}
try {
$sql = 'UPDATE website_content SET
content = :content,
date_added = CURDATE()
WHERE id = :id';
$s = $pdo->prepare($sql);
$s->bindValue(':content', $error_message_text);
$s->bindValue(':id', $id_num);
$s->execute();
}
catch (PDOException $e) {
$error = 'Error: ' . $e->getMessage();
include 'output_mysql_error.php';
exit();
}
}
}
This question is tagged [oop], but the code in it is far from OOP.
Your methods are doing waaaaaaaaaaaaay too much. What you should do is inject the database connection into the constructor of the output_mysql class (which is a terrible name btw).
namespace App\Page;
class Content
{
private $dbConnection;
public function __construct(\PDO $dbConnection)
{
$this->dbConnection = $dbConnection
}
public update($id, $content)
{
$stmt = $this->dbConnection->prepare('UPDATE website_content SET content = :content, date_added = CURDATE() WHERE id = :id');
$stmt->execute([
'id' => $id,
'content' => $content,
]);
}
}
$dbConnection = new \PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pageContent = new \App\Page\Content($dbConnection);
$pageContent->update(1, 'new content');
If you have a method called print_table_cell you are probably doing OOP wrong, because it probably means you code is doing too much and probably violates the Single Responsibility Principle. I mean a class in almost all circumstances would never need to be able to access any column of just any table.
class Model
{
protected $pdo;
/**
* Inject the pdo driver in the model.
*/
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function print_table_cell($tbl_name, $colm_name, $array_index_num)
{
// Use the pdo object $this->pdo
}
}
// Create the connection
$dbName = '';
$dbUsername = '';
$dbPassword = '';
$pdo = new PDO("mysql:host=localhost;dbname=$dbName", $dbUsername, $dbPassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Create your model and inject the pdo object.
$model = new Model($pdo);
$model->print_table_cell() ...
As said above you need to use prepared statements, because PDO will escape the values which prevents SQL injections. But anyway all input data must be filtered : you have some basic filters http://php.net/manual/fr/function.filter-var.php.
The model class should only interact with the database, and doesn't print anything.
For priting output you can use a so called View class that get data from the model and displays it.
class View
{
protected $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function render()
{
echo $this->model->getData();
}
}
class Model
{
protected $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function getData()
{
// Do your query here with $this->pdo and prepared statement.
// and return the data
}
}
$pdo = new PDO(...);
$model = new Model($pdo);
$view = new View($model);
$view->render();

Categories