Database connection in parent constructor not working in child method - php

I have a parent class page, and in it I have a constructor that connects to the database successfully. Here is the code for that:
//establish database connection
function __construct() {
require('db_conn.php');
$this->conn = new mysqli($servername, $username, $password);
}
I want to be able to access the database in the subclass pages- for example the register page class.
I have a function login() in that register subclass that needs to access the database connection variable. Here is the code for that:
private function Register() {
if (isset($_POST['submit'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
//check data is valid i.e. not in database already
$query = mysqli_query($this->conn,'SELECT * FROM users');
if (mysqli_fetch_assoc($query)) {
echo "That email or username already exists!";
} else {
//store data
}
The variable is being detected but seems to not hold a connection, which is strange because I've tried testing it with mysqli_ping() in the same function and it returned true.
If i require the db connection inside the function the query works.
This is my first time using OOP, could be I've missed something straightforward. any help would be great. thanks
I'm aware the queries are wrong- I just wanted to simplify them for the sake of debugging
List item

The first and most obvious issue is that you dont seem to have selected the database you want to use. Remember MySQL manages multiple database.
Note parameter 4 of the mysqli class instantiation should contain a database name
new mysqli('localhost', 'my_user', 'my_password', 'my_db');
whereas yours does not
$this->conn = new mysqli($servername, $username, $password,'MISSING DATABASE NAME');
Can I suggest that while developing you add these lines to the top of all your scripts so that you see any errors in the browser.
<?php
ini_set('display_errors', 1);
ini_set('log_errors',1);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

Related

Mysqli real_escape_string validation not working, after putting database connection in a separate file

I did have this working ok until I changed my connection details to be in a separate file.
db_connection.php
in there I have
class db_connection extends \mysqli
{
function connection(){
$mysqli = new mysqli("hostname", "username", "password", "database");
}
}
In my register.php I have the require_once ('db_connection.php');
Inside I have
require_once ('db_connection.php');
if(isset($_POST['signup-button'])) { //check if form was submitted
$email = $_POST['email'];
$username = $_POST['username'];
$mysqli = new db_connection;
$mysqli->connection();
$email = $mysqli->real_escape_string($email);
$username = $mysqli->real_escape_string($username);
The error message I'm getting is:
Warning: mysqli::real_escape_string(): invalid object or resource db_connection
It is a little confusing what you are actually trying to ultimately accomplish. At first glance, this feels like a case "trying to solve a problem using OOP just for the sake of using OOP". (I apologize if that is offensive, I've just seen similar things like this before.)
First off, using extend on any class should only ever be done if you have a specific reason to do so, for instance if you want to add a method, or get access to a specific bit of functionality.
Second, extending mysqli or any of the database classes, although technically valid, rarely has a legitimate case.
What I think you want is something like this:
class db_connection
{
private ?mysqli $dbh = null;
function connection(): mysqli
{
if (!$this->dbh) {
$this->dbh = new mysqli("hostname", "username", "password", "database");
}
return $this->dbh;
}
}
$mysqli = (new db_connection)->connection();
$email = $mysqli->real_escape_string($email);
$username = $mysqli->real_escape_string($username);
You'll see that I'm creating a class property called dbh (the name can be anything, that is just a common one), and using your method to instantiate it if it doesn't exist, and then returning it.
There is zero advantage in doing this than over regular procedural code, I will note. It isn't right or wrong, it just doesn't help. All of that boilerplate class stuff is identical to these three lines:
$mysqli = new mysqli("hostname", "username", "password", "database");
$email = $mysqli->real_escape_string($email);
$username = $mysqli->real_escape_string($username);
The one advantage of the class, I'll note, is that you could store the mysqli as a static property which essentially guarantees it is instantiated only once, however that's the same as creating a global variable along with possibly a helper function.

Correct way of having multiple php functions to query a single (mysql) database

Working on a PHP website and I've encountered an efficiency issue that I can not solve on my own.
I have a couple of separate php files:
connection.php - connects to the database.
sqlFunctions.php - couple of functions that execute different sql (mysqli) queries, manipulate data and return it.
index.php - file that executes some of the functions from sqlFunctions.php and uses the returned values to display something in the page.
connection.php:
$servername = "DATA"; //Replaced to "DATA" for posting on stackoverflow
$username = "DATA";
$password = "DATA";
$dbname = "DATA";
$con = new mysqli($servername, $username, $password, $dbname);
if ($con->connect_error) {
die("Connection failed: " . $con->connect_error);
}
sqlFunctions.php:
<?php
function query1(){
require('connection.php');
//PDO Query to DB, fetch, store, modify data etc.
mysqli_close($con);
//Return modified data
}
function query2(){
require('connection.php');
//PDO Query to DB, fetch, store, modify some other data etc.
mysqli_close($con);
//Return modified data
}
?>
index.php:
//Simplified version
require('sqlFunctions.php');
<?php echo query1();?>
So I was thinking - initiating a new connection to the db on every function call is not a good idea. And if I would initiate a connection to the db in a function in sqlFunctions.php - I would need to pass another variable/reference/pointer (you know what I mean) to every single function in that file and that is something that I don't want to do.
So what is the best approach to accomplish what I need?
TL;DR;:
Main file calls a function in a separate file
That function executes an sql query and returns data
Returned data is displayed
Without reopening/closing the db connection on every function call.
There are several options.
Option 1. Declare your database connection global inside each function.
sqlFunctions.php:
<?php
require('connection.php');
function query1(){
global $con;
// mysqli code with $con
}
function query2(){
global $con;
// mysqli code with $con
}
?>
Option 2. Use GLOBALS.
connection.php:
...
$GLOBALS['con'] = new mysqli($servername, $username, $password, $dbname);
...
sqlFunctions.php:
<?php
require('connection.php');
function query1(){
// mysqli code with $GLOBALS['con']
}
function query2(){
// mysqli code with $GLOBALS['con']
}
?>
Option 3. Wrap all functions into a class (note capital S).
SqlFunctions.php:
class SqlFunctions {
protected $con;
public function __construct() {
global $con;
// can also pass $con as parameter or init db here
$this->con = $con;
}
public function query1(){
// mysqli code with $this->con
}
public function query2(){
// mysqli code with $this->con
}
}
index.php:
require('SqlFunctions.php');
$sqlFunctions = new SqlFunctions();
<?php echo $sqlFunctions->query1();?>
In this case you can also initialize the connection right inside the class or pass it as a parameter to __construct().

PHP script to connect to SQL

I am at learning stage of PHP. I am using a php file to process form data for sql table and it has server name, user, password and dbname to perform sql-connect query. And of course it is in public directory of website. Is it a safe way or any suggestion is appreciated. example is as follow:
$name = $_POST['name'];
$phn = $_POST['phn'] ;
$servername = "localhost";
$username = "abc";
$password = "abc";
$dbname = "abc";
// Create connection
$conn = mysqli($servername, $username, $password, $dbname);
Connecting using the mysqli extension gives you the ability to use newer MySQL features such as transactional queries and parameterised queries which aren't available using the older mysql extension.
Have a look at MySQL Improved Extension # php.net
Your mysql should be mysqli_connect ()
You forgot new before instantiating the MySQLi connection.
Try this instead:
$conn = new mysqli($servername, $username, $password, $dbname);
You can store database credentials anywhere, but better store them somewhere OUTSIDE of your main PHP folder, using this approach:
/config/db.config.php
<?php
define('DB_USER', 'root');
define('DB_PASS', 'pass');
define('DB_DATABASE', 'database');
define('DB_HOST', 'host');
If you will store it INSIDE of your php folder, each time, when you copy your code from local to web, you will override your configurations. Also, such file is safe (if you will accss it from web, you will see nothing), but I stil advice to put here .htaccess file with deny for all content.
Also, I can advice DO NOT USE mysqli_connect without any wrapper. (better use PDO with parametrised queries). But, if you want to work with mysqli, better search in web for good wrapper, or write it by self. From my experience, most better way to work with mysqli is create class with static functions:
class DB {
public static function init($dbHost, $dbUser, $dbPass, $db);
public static function getTable($query);//get array of arrays
public static function getRow($query);//get array (one database row)
public static function getCell($query);//get single value
public static function getColumn($query);//get array (column)
public static function query($query);//update, delete, insert
}
because with this class you will be able to get data in any place of your script using something:
$list = DB::getTable("select * from table");
please try this
<?php
$servername = "localhost";
$username = "abc";
$password = "abc";
$dbname = "abc";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
$name = $_POST['name'];
$phn = $_POST['phn'] ;
?>

how to avoid the new PDO(...) line of code to appear too often?

There is something, as a newbie, that a I want to understand about About database connections.
I am starting off from a tutorial on PHP which has this structure:
Connect.php:
<?php
$username = "dbusername";
$password = "dbpassword";
$host = "localhost";
$dbname = "dbname";
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
try
{
$db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options);
}
catch(PDOException $ex)
{
die("Failed to connect to the database: " . $ex->getMessage());
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
header('Content-Type: text/html; charset=utf-8');
session_start();
?>
Login.php:
<?php
require("connect.php");
// some code not important for this question,
//that handles login with a session…
?>
various_file_in_the_login_system.php:
<?php
require("connect.php");
// some code that checks if user is logged in with session_ …
// some code that does need the database connection to work
?>
All other files also contain that require("connect.php"); line. It works, but I just don’t know what these connection request to the server – I may not be using the right vocabulary -- end up doing to the server. They are superfluous if the connection is not timed out, are they not?
I found a post which talked about doing a singleton for PDO, and a post which makes me feel like never using persistent connections in my life.
Does this design causes excessive connection churning?
Perhaps servers can handle very many request for connection per second, perhaps a server has its own internal persistent connection mode, or implements connection pooling…
Or the PDO object handle the problem of asking connection too often for no reason…
PDO + Singleton : Why using it?
What are the disadvantages of using persistent connection in PDO
This is what I can recommend for your database connection:
Make a class for the connection:
class Database{
private static $link = null ;
public static function getConnection ( ) {
if (self :: $link) {
return self :: $link;
}
$dsn = "mysql:dbname=social_network;host=localhost";
$user = "user";
$password = "pass";
self :: $link = new PDO($dsn, $user, $password);
return self :: $link;
}
}
Then you can get the connection like this:
Database::getConnection();
The Singleton Pattern is hard to scale - However, I think it will probably be fine for your needs. It takes a lot of load off your database.
I don't think you will be able to avoid the multiple includes.
There is a php.ini setting for prepending a file to every script -> http://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file
How about you change to
require_once('connect.php');
in all locations?
Also you should probably remove session_start() and HTTP header logic from a section of code that has to do with establishing a DB connection. This simply does not make sense there.

Do I have to include my db connector file each time I run a query with PDO?

I've got the following saved into my dbConnect.php file
$host = 'localhost';
$username = 'root';
$pass = 'mypass';
try {
$dbh = new PDO("mysql:host=$host;dbname=horh_new", $username, $pass);
} catch (PDOException $e) {
echo $e->getMessage();
}
What is the best method to include this into my script? Right now, I've got a function to insert a user into the database which does something like this:
function insertUser($username) {
include("dbConnect.php"); // i'd like to not have to include this each time
$query = $dbh->prepare("INSERT INTO users (username) values (?)");
$query->bindParam(1, $username);
$query->execute();
}
Obviously, the more functions I have the more times I have to include this dbConnect.php file. Should I instead include it into a class with private variables for $username, $host, and $pass (so there are no conflicts when using the same variables passed into the function?
Then include the class once in the header of my script instead of in every single function? I'm quite new to PDO, so I'd like to figure out the most efficient method of doing this. Thanks.
Every time you include that, you are opening a new connection in the scope of that function. Simply include it on your front-facing web file and global your db connection for each function. Do not include this file more than once, otherwise you will be opening that many more connections, which causes unnecessary slowdowns.
index.php example:
<?php
include("dbConnect.php");
include("somefunctions.php");
// more stuff, front-facing web stuff, using stuff in somefunctions.php
somefunctions.php:
<?php
function doSomething()
{
global $dbh;
$query = $dbh->prepare("INSERT INTO users (username) values (?)");
// etc.
}

Categories