i'm using Slim framework to provide an API to our clients. I'm focused on Java so that could the the point, because the problem is related with database connection.
Every request connect to the database throw PDO like
$dbh = new PDO($param1, $param2, $param3);//php 7.1
So as php don't have a connection pool i understand each request (maybe at the same time) starts a new connection throw the database.
But i'm experimenting a kind of situation here.
If one request starts a transaction for inserting or updating something, next requests will wait until this transaction finish, but it is on a different thread, so i'm thinking on table locks? or something like each request is getting the same connection.
THE PROBLEM:
So if they are in different threads with a different connection how
they need to wait until transaction ends for the first request.
My database source class is something like
class DataBaseConfig {
public static function getConn()
{
$dbh = new PDO($param1, $param2, $param3);
$dbh->exec("set names utf8");
return $dbh;
}
}
And i use it like
$db = DataBaseConfig::getConn();
$db->beginTransaction();
//code
$db->commit();
I'm missing something sure, so can someone help me with this problem?
Thanks!
NEWS! EDIT
#YourCommonSense thank you it was finally a session configuration. I
didn't know that php start_session(); locks the session file so that's
what was happening. Thanks a lot!
link: https://ma.ttias.be/php-session-locking-prevent-sessions-blocking-in-requests/
Related
Pre-emptive apology: This post contains basic questions.However, I have searched and I have not found an answer, if there is one...sorry.
I am following some youtube tutorials for making a basic ajax web chat, and in the tutorial the person is using MySQLi to connect to the DB. I want to create the same ajax chat application except I want to use PDO instead of MySQLi.
The person uses these two files:
config.php
<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'bucky_chat');
define('DB_PASSWORD', '123456');
define('DB_NAME', 'bucky_chat');
?>`
chat.class.php
<?php
require_once('config.php');
require_once('error_handler.php');
class Chat {
private $mysqli;
//constructor opens DB connection
function __construct(){
$this->mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
}
//destructor closes db connection
function __destruct(){
$this->mysqli->close();
}
}
?>
I'm trying to replicate the above snippets with PDO. The problem is that I'm not sure how to adapt the PDO examples I have looked at to do this.
First of all I'm confused as to why he defined these things in a separate file.. are there any benefits in doing this?
In another PDO tutorial I am looking at I see it can be done the followings way:
<?php
$config['db'] = array(
'host' => 'localhost',
'username' => '',
'password' => '',
'dbname' => ''
);
$db = new PDO('mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['db_name'], $config['db']['username'], $config['db']['password']);
//some code
$db = null; //closes connection
?>
`
I think this is what I need to use (in a try catch block), but why does he put these things in an array? it seems to over complicate things... why not just variables? But does this code replicate the mysqli example? Howcome I don't see __construct() being used with PDO?
Some minor questions...
When creating a website with a user, is there a standard place to store DB connection?
Any book recommendations?
Sorry for all these questions, All help is strongly appreciated!
To answer your questions:
First of all I'm confused as to why he defined these things in a separate file
The authentication details are defined in a second file because if you create another query script, now both scripts can include the authentication details. If the authentication details change, you only need to update one file. If you are just writing a simple application, than just keep everything in one file.
but why does he put these things in an array
I think this is just done in-case the authentication details are needed someone else in the script (much like the defined globals from your first sample). Its often best practice to define parameters into variables (even if you use the variable once). This way, if you typo a variable, you will get an error; versus copy and pasting the same string over and over again.
Howcome I don't see __construct() being used with PDO
When ever you create a new object in PHP, you do not need to call __construct, it is called automatically with the "new" statement.
$PDOConnection = new PDO($dsn, $username, $password);
When creating a website with a user, is there a standard place to store DB connection
Definitely make sure the authentication details are stored in an inaccessible file to the public. The connection object has no harm to be accessed by the public (unless of course you need to authenticate the client (website user) before establishing a database connection). Is is best practice to always begin your (secure) PHP files with:
<?php
BUT... never end the file with "?>". If an extra character is inserted after the "?>" on accident, your web server could display your whole script to the world (of course your Apache, etc... would have to be configured wrong). Like I said... best practices.
Any book recommendations?
Googleing "php arcitechture best practices" may help.
You are confusing WAY TOO MUCH things that can be explained in one answer. you don't even know what to ask.
Please, don't take the art of programming as a some sort of cheap trick one can learn in 2 hours. To write a AJAX-based chat one need to learn for at least several months. To learn by understanding, not by copy-pasting. To learn step by step, going from variables to arrays, from arrays to functions, from functions to classes and so on - not by throwing all the code they find in one bowl and then asking on SO how to deal with all that. One cannot get to another step without having understand a previous one. And of course all these youtube tutorials are definitive pieces of useless rubbish.
some of your confusions are:
__construct() method actually has nothing to do with PDO. Nor with mysql. this is a Chat class method. And method which is all wrong. Chat class shouldn't create its own connection but use already created one.
This thing on variables vs. array vs. constants doesn't really matter. To have connection options in a separate file is a good thing but nonetheless you need to have a connection code in the separate file as well, to avoid writing connection code in the every file.
You should not use this code in a try catch block (unless you have an idea what to do in case of error, which I doubt you have).
Before starting for a chat, you have to learn smaller, simpler applications, like telephone book or the like, to learn basic database operations, from which you'll be later able to build ANY application, like any house can be built of bricks.
PDO basics you can get right here, in the tag wiki. But OOP basics is not that easy.
First the reason you define config in different file is so that you can just include that file instead of writing the database configuration anytime you want database access. It is preferred best practice.
you can do:
try
{
$PDOConnection = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.'', DB_USER, DB_PASS);
$PDOConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Do you stuffs
$PDOConnection = null;
}
catch(PDOException $e)
{
//Do something with error
}
Why not just do:
<?php
$hostname = 'host';
$dbname = 'dbname';
$username = 'uname';
$password = 'pw';
try {
$db = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $ex) {
echo "An Error occurred!";
}
?>
In a separate PHP file I call mine dbPDO.php and then have:
require_once("dbPDO.php");
In your PHP pages. And then run queries by doing:
EDIT: to condense my answer.
$username = $_POST['username'];
$stmt = $db->prepare("SELECT field1, field2, field3, etc FROM mytable WHERE username = :username");
$stmt->bindParam(':username', $username);
$stmt->execute();
while ($r = $stmt->fetch()) {
$field1 = $r['field1'];
$etc = $r['etc'];
}
Make sure you bindParam and use the ':' in the query. Don't just put WHERE username = $username or WHERE username = $_POST['username'] That would led you prone to SQL Injection. Also, I didn't show it here, but you should have some sort of exemption handling for each query. I place the whole query in a Try/Catch, but I hear there are other ways to deal with it. I personally think its personal preference.
First of all you don't need an array nor variables, you can directly input the configuration..like:
try { //try connection
//common db
$db = new PDO('mysql:host=localhost;dbname=some_db_name', 'some_usernane', 'some_pass');
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) { //connection failed
die("Oh no! It seems we took too long to respond, we are sorry for that..");
}
Secondly _constructor() means that whenever the class Chat is called everything in the _constructor() is executed .
Here is a good tutorial for PDO http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
I am doing project using mongodb and zendframework 2 so here I create connection in the constructor
private $conn;
public function __construct(){
$this->conn = new \MongoClient('mongodb://example.com:27017', array("connect" => TRUE));
}
It contain several actions to perform database operations like createdb, dropdb, renamedb like wise. so I close that connection within the __distruct() method
public function __destruct(){
$this->conn->close();
}
my code works fine. but I would like to know is this ok?
PHP closes database connections automatically.
You can read more about this in this post
however
read this
quote:
"Open connections (and similar resources) are automatically destroyed at the end of script execution. However, you should still close or free all connections, result sets and statement handles as soon as they are no longer required. This will help return resources to PHP and MySQL faster."
So basically, in case you have tons of things going in and out of the database, then yes, you might want to close right after.
In my opinion it is rather optional and your own choice wether to kill the process or not.
I am used to mysql database access using the procedural mysql method. I am a beginner - intermediate programmer.
I am trying to learn the PDO api, however all resources which discuss using PDO show the connection string, username and password.
e.g.
<?php
try {
$db_conn = new PDO('mysql:host=localhost;dbname=databaseName','username', 'password');
}
catch (PDOException $e) {
echo 'Could not connect to database';
}
$sql = 'SELECT * FROM Products';
$stmt = $db_conn->prepare($sql);
...
...
...
?>
What I want, and think would be better programming is to put my PDO connection into a new file. then where I want to run an SQL query, I require_once('PDO.php') or similar.
The problem I have with this is as follows:
How do I close the connection? Simply $db_conn = null; ??
Should I close the connection after each query is run, then re-open the connection?
Should I close the connection or is it automatically destroyed when the user closes the browser?
I am working from a book called PHP Master: Writing Cutting Edge Code. http://www.sitepoint.com/books/phppro1/ and this has completely omitted any reference to closing the connection / destroying the object after it has been used.
Furthermore, I have looked at online tutorials, and they all connect to the database using PDO inline as opposed to having a separate database connector. This I am not happy with for many reasons:
I have to type username & password to connect every time.
If I get a developer to take a look at code / write some code, they will all have access to the database.
If I change the DB username & Password, then each file which connects to the database will need to be updated.
Could anybody recommend a better resource? Could anybody advise on what is the best practice way to do this?
Many thanks
Your question about how to store the database name, username and password have nothing to do with the capabilities of PDO. This is an implementation choice. The way you use to work with procedural functions can also be applied to PDO, the difference is that with PDO you work with objects instead.
So for simplicity, store the PDO creation of an object, either in a function or class, in which you can create the PDO instance anytime, e.g.
function createPDO($cfg) {
try {
return new PDO("mysql:host=".$cfg['host'].",port:".($cfg['port']).";dbname=".($cfg['name']).";",$cfg['username'], $cfg['password']);
} catch(PDOException $e) {
// handle exceptions accordingly
}
}
You can centralise these in whatever PHP file you like to include, just like you were used with the procedural functions.
You have two choices, either put all the relevant database information inside the createPDO, or use something like a config ($cfg) variable to store all this information.
$config = array();
$config['db'] = array(
'host' => 'localhost',
'name' => 'databse',
'username' => 'userx',
'password' => 'passy'
/* .. etc */
)
Using the createPDO function would be as followed
$db_conn = createPDO($config['db']);
For connections closing, each connection made to the database automatically disconnects after PHP exits its execution. You can however, close the connection if you wish, by setting the variable of the PDO object you assigned it to, in this example (and in yours) $db_conn to null
$db_conn = null; // connection closed.
The PDO has a manual http://php.net/manual/en/book.pdo.php here, which is a good start getting to know PDO a bit better.
You do not close the connection after a query, you simply leave it open for the next query. When PHP exists and your page is shown, the connection will be closed automatic.
It is a good idea to put the db stuff in a separate file and include that.
Even better, put all your db stuff in a class in use that.
Have a look at the pdo php page. Although not the best examples, they should get you started.
I have a webpage with some mysql querys,
I must start new db connection and db close after every query or its more efficiently start an only one db connection at the top of the code and close at the bottom of the script?
Thanks!
Never create a new connection for every query; it's very wasteful and will overburden your MySQL server.
Creating one connection at the top of your script is enough - all subsequent queries will use that connection until the end of the page. You can even use that connection in other scripts that are include()ed into the script with your mysql_connect() call in it.
I prefer to create some sort of class called Database of which upon creation will create a database connection using mysqli (OOP version of mysql).
This way i do not have to worry about that and i have a static class that has access to the database.
class MyAPI {
private static $database = false;
public static function GetDatabase() {
if (MyAPI::$database === false) {
MyAPI::$database = new Database(credentials can go here)
}
return MyAPI::$database;
}
}
Now your system with the includsion of your API and your database can access the database and its initialization code does not have to be peppered around your files depending on what part of the program is running and your database/connection will not be created if it is not needed (only until it is called).
Just for fun i also like to have a function in my Database class that will perform a query and return its results, this way i do not have to have the SAME while loop over and over again throughout my code depending on where i make these calls.
I also forgot to answer your question. No multiple connections! its baaaad.
Only create one connection. You don't even have to close it manually.
multiple connexion is better for security and tracking.
if you're going though a firewall between front and back there will be a timeout defined so a single connection will be a problem.
but if your web server is on the same host as mysql, a single connection will be more efficient.
HI everyone, I was just wondering what the best way to make multiple queries against tables in a mysql databases is. Should I be making a new mysqli object for every different .php page ($mysqli = new mysqli("localhost", "root", "root", "db");)?
Or is there a way to reuse this one time over all php files in my website? Any suggestions would be pretty cool
My vote would be to take an OOP approach. I would have one script that has a DB conn class in it and a method in that class to check if a connection exists and if it does returns the connection object. You could have that db class script referenced [ include_once(); ] on the pages that need to access the database. Then it would be a matter of instantiating the db object, firing the "if-exists" method and if it returns true then just utilize the existing connection within the object.
You could also take a look at utilizing persitent connections to the DB
Persistent connections
However honestly you will be better off in the long run and scalability of your application to handle the db connection management yourself rather then leaving a connection constantly open.
Here is an example of how I would structure that class:
As a note, made by #alex, the mysql_error() should not be echoed to the page in an environment where the display_errors() is set to display all warnings. (e.g error_reporting(E_WARNING);)
class dbconn {
protected $database;
function __construct(){
$this->connect();
}
protected function connect() {
$this->database = mysql_connect('host', 'user', 'pass') or die("<p>Error connecting to the database<br /><strong>" . mysql_error() ."</strong></p>" );
mysql_select_db('databasename') or die("<p>Error selecting the database<br />" . mysql_error() . "</strong></p>");
}
function __destruct(){
mysql_close($this->database);
}
function db(){
if (!isset($this->database)) {
$this->connect();
}
return $this->database;
}
}
You need to create the connection for each page, as each PHP script's lifetime is that of the request.
However, you can place the connection code in one file and then include it from all pages.
You could create a connect.php that validates it's being included by your application, and then creates a DB connection.
You could then include that file at the beginning of your application's init, or the beginning of any independent script that needs a connection =)
Depends on structure of website. If you have:
<a herf='login.php'>login</a>
<a herf='register.php'>register</a>
<a herf='about.php'>about</a>
..., then you'll have to connect in every PHP file, i.e., in login.php, in register.php and in about.php. To make it easier, I would either create config.php file which holds user/pass, or even do like Shad said.
You might also have index.php that contains something like this:
if ( !isset($_GET['module']) ) {
$_GET['module'] = 'about';
}
switch ( $_GET['module'] ) {
default:
case 'about':
include 'about.php';
break;
case 'login':
include 'login.php';
break;
case 'register':
include 'register.php';
break;
}
And HTML code:
<a herf='?module=login'>login</a>
<a herf='?module=register'>register</a>
<a herf='?module=about'>about</a>
In this case you can connect in index.php and then pass the connection to all other involved files.
The 2nd way seems to be more common to me, i.e., it feels more intuitive, more handy and that's what I always do.
I believe that in some cases it might be worthy (performance-wise) to use persistent connections and reserve/release connection when needed (either for transaction or even for single query). For example, simple system that I'm now working with takes 70ms-100ms to generate, and it takes only 40ms-50ms to do SQL queries. If using "single connection" approach, it means that connection is wasted for about 50% of time, while "reserve/release connection when needed" with persistent connections would not have such issue.
One more thing - I would advise you to create some wrapper, i.e., some DBConnection class that connects to DB in constructor and has methods like select() (returns array of data), selectValue() (returns single value, e.g., $db->selectValue('select count(*) from user') would return (int)$numberOfUsers), some exec() for inserts and updates etc.