My controler call a method who is requested the database and return the result.
$connect = $this->connectBDD();
$rq = "SELECT naf, libelle FROM mytable WHERE naf ILIKE '$txt%'";
$t = $connect->prepare($rq); $t->execute();
$t->setFetchMode(\PDO::FETCH_OBJ);
$tab = array();
while($top = $t->fetch()) {
$tab[] = array(
"text" => $top->naf . ": " . $top->libelle,
"value" => $top->naf
);
}
$t->closeCursor();
return $tab;
The problem comes from the first line $connect = $this->connectBDD(); who open the connexion. It takes times, ~ 1 seconde, and because this method is call very often (auto completion system), I need to memorize the connection to not reconnect at each call.
I try to memorize $connect in session
if( null === $this->app['session']->get('ac') ) {
$this->app['session']->set('ac', $this->connectBDD() );
}
$connect = $this->app['session']->get('ac');
$rq = "SELECT naf, libelle FROM mytable WHERE naf ILIKE '$txt%'";
$t = $connect->prepare($rq); $t->execute();
$t->setFetchMode(\PDO::FETCH_OBJ);
$tab = array();
while($top = $t->fetch()) {
$tab[] = array(
"text" => $top->naf . ": " . $top->libelle,
"value" => $top->naf
);
}
$t->closeCursor();
return $tab;
But it's worse, as if I have an infinite loop...
So, how can I call my method without reconnect the database at each call ?
Thanks for help
Try to make persistent connection in connectBDD
$dbh = new PDO('....', $user, $pass, array(
PDO::ATTR_PERSISTENT => true
));
http://php.net/manual/en/pdo.connections.php
Related
Before Marking my question as duplicate please give any example or link where i can understand, i am learning PHP. hope you understand.
I am Trying to insert data using database_class and insert function.
Here's my database class.
//db_class.php
class database {
var $_sql = '';
var $_resource = '';
var $_result = '';
var $_insertId = '';
function connect() {
global $glob;
$host = $glob['localhost'];
$user = $glob['root'];
$pass = $glob[''];
$db = $glob['crestdb'];
try {
$this->_resource = new PDO('mysql:host='.$host.';port=3306;dbname='.$db.'', $user, $pass);
$this->_resource->query("SET SQL_BIG_SELECTS=1");
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
function insert($table, $dbFields) {
$field = array();
$value = array();
foreach ( $dbFields as $k => $v) {
//$v = addslashes(stripslashes($v));
$v = (stripslashes($v));
$field[] = $k;
$qmark[] =":".$k;
$value[":".$k] = $v;
}
$f = implode('`,`',$field);
$val = implode("','",$value);
$q = implode(",",$qmark);
$insertSql = "INSERT INTO `$table` (`$f`) VALUES ($q)";
$stmt = $this->_resource->prepare($insertSql);
$stmt->execute($value);
$_result=$this->_resource->lastInsertId();
$this->_insertId=$_result;
return $_result;
}
and am using it as
addcat.php
include( "db_class.php");
$obj = new database();
if(isset($_POST['submit'])){
$dbFields = array(
'cname' => $_POST['cname'],
'priority' =>$_POST['priority'],
'status' => $_POST['status'],
);
$obj->insert("category",$dbFields);
}
using this i am getting error as per my TITLE suggest.
i think i am making mistake in addcat.php am i calling this function wrongly?
this is the error:- Uncaught Error: Call to a member function prepare() on string in C:\xampp\htdocs\def\database.class.php:82 Stack trace: #0 C:\xampp\htdocs\def\addcat.php(42): database->insert('category', Array) #1 {main} thrown in C:\xampp\htdocs\def\database.class.php on line
By searching lot in google i tried to make different class for connection.
and #Felippe and #Aynber you both were right i have made an class using your suggestion.
class database{
var $_resource ;
var $_result = '';
var $_sql = '';
var $_insertId = '';
var $host = 'localhost';
var $user = 'root' ;
var $pass = '';
var $dbname = 'crestdb';
var $error;
public function __construct(){
// Set DSN
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
// Set options
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
// Create a new PDO instanace
try{
$this->_resource = new PDO($dsn, $this->user, $this->pass, $options);
}
// Catch any errors
catch(PDOException $e){
$this->error = $e->getMessage();
}
}
maybe it still needs improvement but it works for me now !!.
Forgive me if the question is a little odd
I can clarify if needed:
I have the code that can connect to a mysql database as normal, however i have encapsulated it as a class:
<?php
define("HOST", "127.0.0.1"); // The host you want to connect to.
define("USER", "phpuser"); // The database username.
define("PASSWORD", "Secretpassword"); // The database password.
class DBConnection{
function conn($sql, $database){
$DB = new mysqli(HOST,USER,PASSWORD,$database);
if ($DB->connect_error){
die("Connection failed: " . $DB->connect_error);
exit();
}
if ($result = $DB->query($sql)){
return TRUE;
$DB->close();
}
else{
echo "Error: " . $sql . "<br>" . $DB->error;
$DB->close();
}
}
}
?>
I have done it this way so i can include this class in any subsequent php page and allow them to send it an sql statment and the database, see below as an example:
$sql = ("INSERT INTO users (first_name, last_name, username, email, password, group_level) VALUES ('John', 'Doah','JDoah', 'example#email', 'password', 'user')");
$DB = new DBConnection;
$result = $DB->conn($sql,"members");
if ($result ==TRUE){
return "Record added sucessfully";
}
This works fine.
however, im looking to send other sql statments to DBConnection.
How do i do that and to have it pass back any results that it recives? errors, boolean, row data etc. The caller will worry about parsing it.
Hopefully that makes sense.
This is an old class I used to use way back in the days of mysql still works but will need to be updated for mysqli or newer
class DBManager{
private $credentials = array(
"host" => "localhost",
"user" => "",
"pass" => "",
"db" => ""
);
function DBManager(){
$this->ConnectToDBServer();
}
function ConnectToDBServer(){
mysql_connect($this->credentials["host"],$this->credentials["user"],$this->credentials["pass"]) or die(mysql_error());
$this->ConnectToDB();
session_start();
}
function ConnectToDB(){
mysql_select_db($this->credentials["db"]) or die(mysql_error());
}
function Insert($tableName,$data){
$parameters = '';
$len = count($data);
$i = 0;
foreach($data as $key => $value){
if(++$i === $len){
$parameters .= $key . "='$value'";
}else{
$parameters .= $key . "='$value'" . ", ";
}
}
$query = "INSERT INTO $tableName SET $parameters";
mysql_query($query) or die(mysql_error());
return true;
}
function GetRow($tableName,$select,$where){
$selection = '';
$len = count($select);
$i = 0;
foreach($select as $key){
if(++$i === $len){
$selection .= $key;
}else{
$selection .= $key . ",";
}
}
$whereAt = '';
foreach($where as $key => $value){
$whereAt .= $key . "='$value'";
}
$query = "SELECT $selection FROM $tableName WHERE $whereAt";
$result = mysql_query($query);
while($row = mysql_fetch_array($result)){
return $row;
}
}
}
The key things here is you can create a persistent connection to your database without rewriting a bunch of code
Example
global $DB;
$DB = new DBManager();
Since the connection happens in the constructor you will now have a connection on the page you call this code and can begin getting and setting to the database through use of $DB->GetRow() and $DB->Insert() which makes things much easier and was modeled after the $wpdb instance which is a class that manages the database in wordpress sites
Examples
For these examples we will assume you have a table as such
Insert new student
//create an associative array
$data = array(
"student_id" => 1,
"birth_date" => "02/06/1992",
"grade_level" => 4
);
//Send Call
$dm->Insert("student",$data);
Get data
//Create selection
$selection = array("grade_level");
//Create associative array for where we want to find the data at
$where = array(
"id" => 1
);
//Get Result
$result = $dm->GetRow("student",$selection,$where);
//do something with result
echo $result->grade_level;
I have a custom class that takes a sql connection as a parameter. I use that to populate the class, and then I'm trying to use it again to modify the results on screen. But after the first use, I can't use it anymore.
connection.php:
$conn = new mysqli('localhost', 'root', '', 'loveConnections');
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
personalityProfile.php (front end)
if (!isset($_SESSION['interests'])) {
$interests = new Interests($conn, $_SESSION['id']);
$_SESSION['interests'] = $interests;
} else {
$interests = $_SESSION['interests'];
}
interestsObject.php
class Interests {
// properties
public $conn;
public $id;
public $interestsArray = [];
public function __construct($conn, $memberId = null, $intArray = [
'basketball' => false,
'bowling' => false,
'movies' => false,
]) {
$this->conn = $conn;
$this->id = $memberId;
$this->interestsArray = $intArray;
$this->popArraySql();
}
public function popArraySql() {
$memInterests = [];
$sql = "SELECT i.interest
FROM memberInfo m
Join MemberInterestLink mi on (mi.memberID_FK = m.memberID_PK)
Join interests i on (mi.interestID_FK = i.interestID_PK)
WHERE memberID_PK = $this->id";
$result = $this->conn->query($sql);
$this->conn works perfectly here
foreach ($result as $row) {
array_push($memInterests, $row['interest']);
}
foreach ($this->interestsArray as $key => $value) {
for ($i=0; $i<sizeof($memInterests); $i++) {
if ($memInterests[$i] === $key) {
$this->interestsArray[$key] = true;
}
}
}
}
public function insertUpdateQuery() {
var_dump($this->conn);
foreach ($this->interestsArray as $key => $val) {
echo $key . "<br>";
$select = "SELECT interestID_PK from interests where interest = '" . $key . "'";
echo $select;
$result = $this->conn->query($select);
when I try and use it later though, I get a Warning: mysqli::query(): Couldn't fetch mysqli. Additionally, if I try and var_dump it, I get Warning: var_dump(): Property access is not allowed yet
var_dump($result);
if ($val === true) {
$insert = "INSERT INTO MemberInterestLink (memberID_FK, interestID_FK) VALUES ($this->id, $interestKey)";
$this->conn->query($insert);
} else {
$delete = "DELETE FROM MemberInterestLink WHERE interestID_FK = $interestKey";
$this->conn->query($delete);
}
}
}
}
I never close the connection, which is what most of the related answers suggested the cause may be. It's like my $conn variable just stops working after the first use.
I am attempting to set up a class for the simplification of MySQLi queries using the mysqli class. However, when I set up my class to accept an instance of mysqli, I receive this error:
Undefined variable: dbobj in C:\wamp\www\inc\classes\ezsql.class.php on line 93
I've never really done dependency injection before, plus my coding skills aren't with me today, so syntax mistakes might be plentiful.
Here's the class I've created:
<?php
/*/////////////////////////////////////////////////////////////////////////////////////////////
EZSQL
A PHP class that utilizes the PDO MySQLi DB class to make database querying easier and quicker.
/////////////////////////////////////////////////////////////////////////////////////////////*/
class EZSQL {
public $dbobj;
public function __construct( mysqli $dbobject ) {
echo "var_dunp before making this->dbobj\n";
var_dump( $dbobj );
if ( is_object( $dbobject ) ) {
$this->dbobj = $dbobject;
} else {
// Just in case...
die( "EZSQL Error #0: EZSQL must be initialized with a PDO MySQLi DB instance." );
}
echo "var_dunp after making this->dbobj\n";
var_dump( $this->dbobj );
}
public function select( $exp, $table, $where ) {
// Make $where optional
if ( isset( $where ) ) {
$queryString = "SELECT {$exp} FROM {$table} WHERE {$where}";
} else {
$queryString = "SELECT {$exp} FROM {$table}";
}
if ( $returnObj = $this->dbobj->query( $queryString ) ) {
$return = $returnObj->fetch_assoc();
return $return;
} else {
// Some error handling
die( "[EZSQL]: SQL SELECT query error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
}
public function insert( $tab, $cols, $values ) {
// Create the general query string format
$queryString = "INSERT INTO {$tab} (";
$colsCt = count( $cols );
foreach ( $cols as $key=>$col ) {
if ( $key != ( $colsCt - 1 ) ) {
$queryString .= "{$col}, ";
} else {
$queryString .= "{$col})";
}
}
// More general formatting
$queryString .= " VALUES (";
$valCt = count( $values );
foreach( $values as $key=>$value ) {
if ( $key != ( $valCt - 1 ) ) {
$queryString .= "{$value}, ";
} else {
$queryString .= "{$value})";
}
}
if ( $query = $this->dbobj->prepare( $queryString ) ) {
$query->execute();
} else {
die( "[EZSQL]: SQL INSERT query prepare error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
}
public function createTable( $name, $ino, $colData ) {
// Create the general query string format
$queryString = "CREATE TABLE";
if ( $ino ) {
$queryString .= " IF NOT EXISTS";
}
$queryString .= " {$name}";
$colCt = count( $colData );
$queryString .= " (";
$iter = 1;
foreach ( $colData as $name=>$type ) {
$iter++;
if ( $iter != ( $colCt ) ) {
$queryString .= " {$name} {$type},";
} else {
$queryString .= " {$name} {$type});";
}
}
if ( !$this->dbobj->query( $queryString ) ) {
die( "[EZSQL]: SQL CREATE TABLE query error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
}
}
?>
Line 93 is contained inside the function createTable, specifically this if statement:
if ( !$this->dbobj->query( $queryString ) ) {
die( "[EZSQL]: SQL CREATE TABLE query error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
Any and all help will be greatly appreciated, as I can't quite tell what is wrong.
Again, keep in mind I am new to dependency injection. Syntax errors in PHP are not a rarity for me.
Thanks.
Edit 1: Here's the connection I'm using in my index.php page:
<?php
require( "inc/classes/ezsql.class.php" );
// require( "inc/config.php" );
// require( "inc/proc/db.php" );
$host = "127.0.0.1";
$user = "root";
$pass = "";
$db = "testdb";
$port = "3306";
$db = new mysqli( $host, $user, $pass, $db, $port );
echo "var_dunp before creating instance of EZSQL\n";
var_dump( $db );
if ( !$db ) {
die( "error" );
}
$ezsql = new EZSQL( $db );
$cols = array(
"int" => "int",
"text" => "varchar(255)"
);
$ezsql->createTable( "test1", TRUE, $cols );
?>
Edit 2: Added var_dump()s to certain locations. See this Pastebin for what they return.
Use a pdo wrapper such as this:
http://pastebin.com/AHdJkCBz
Then in the same directory, add settings.ini.php like this http://pastebin.com/cu1kY8kL
Do not commit this settings file to your repository. Copy and paste it always.
The way to call this would be:
function checkPassword($email, $password)
{
$db = new db();
$binding = array('emailId'=>$email, 'hashed_password'=>md5($password));
return $db->single("SELECT id FROM members WHERE pc_address = :emailId AND hashed_password = :hashed_password", $binding);
}
Check the whole class for detailed methods.
I have also made two general purpose functions to add/update database.
function assetsUtilInsert($table, $params, $debug=false){
$db = new db();
if($table && is_array($params)){
$bindings = $params;
if(!empty($bindings)) {
$fields = array_keys($bindings);
$fieldsvals = array(implode(",",$fields),":" . implode(",:",$fields));
$sql = "INSERT INTO ".$table." (".$fieldsvals[0].") VALUES (".$fieldsvals[1].")";
}
if($debug==true)
echo $sql;
$result = $db->query($sql,$bindings);
return $db->lastInsertId();
} else {
assetsUtilInvokeError($this->registry->log, "Could not insert because either table does not exist or parameters is not an array");
}
}
function assetsUtilUpdate($table, $params, $where, $exit=0){
$db = new db();
$sql = '';
if($table && is_array($params) && is_array($where)){
$sql = "UPDATE $table SET ";
foreach($params as $key => $val){
$sql .= $key ."=:$key, ";
}
unset($key); unset($val);
$sql = substr($sql, 0, (strlen($sql)-2));
$sql .= " WHERE ";
foreach($where as $key => $val){
$sql .= $key ."=:$key AND ";
}
unset($key); unset($val);
$bindings = array_merge($params, $where);
unset($params); unset($where);
$sql = substr($sql, 0, (strlen($sql)-4));
if($exit==1){
echo $sql; exit;
}
return $db->query($sql, $bindings);
} else {
assetsUtilInvokeError($this->registry->log, "Could not insert because either table does not exist or params is not an array or where condition is not an array");
}
}
I have used log4php for logging. You could adapt with this code.
Just changing the settings.ini.php for driver can help you use the same code for different databases supported by PDO.
Fixed.
I am an idiot, apparently, and screwed up a few things.
Thanks for the suggestions, but I'm not doing this professionally, so I don't care about injection attacks at this point in time. All of this is hosted locally and not port forwarded, so none of this data really matters.
Input sanitization is next on my list, though.
Check if you have enabled mysqli extension or just test if you can instance outside your class.
Also can we see how you instance and use your class when you get this error.
EDIT
Check mysqli object with var_dump() when you pass to your constructor.
I need to get username, password etc from the wp-config file to connect to a custom PDO database.
Currently I have another file where I have this info, but I would like to only use the wp-config.
So how can I read the different properties of wp-config?
I have even defined my own constants in in wp-config.php and managed to retrieve them in theme without any includes.
wp-config.php
define('DEFAULT_ACCESS', 'employee');
functions.php
echo "DEFAULT_ACCESS :".DEFAULT_ACCESS;
outputs DEFAULT_ACCESS :employee
Here's some same code.
// ...Call the database connection settings
require( path to /wp-config.php );
// ...Connect to WP database
$dbc = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
if ( !$dbc ) {
die( 'Not Connected: ' . mysql_error());
}
// Select the database
$db = mysql_select_db(DB_NAME);
if (!$db) {
echo "There is no database: " . $db;
}
// ...Formulate the query
$query = "
SELECT *
FROM `wp_posts`
WHERE `post_status` = 'publish'
AND `post_password` = ''
AND `post_type` = 'post'
";
// ...Perform the query
$result = mysql_query( $query );
// ...Check results of the query and terminate the script if invalid results
if ( !$result ) {
$message = '<p>Invalid query.</p>' . "\n";
$message .= '<p>Whole query: ' . $query ."</p> \n";
die ( $message );
}
// Init a variable for the number of rows of results
$num_rows = mysql_num_rows( $result );
// Print the number of posts
echo "$num_rows Posts";
// Free the resources associated with the result set
if ( $result ) {
mysql_free_result( $result );
mysql_close();
}
I would just include the file then I would have access to the variable in it varibales.
<?php
require_once('wp-config.php');
echo DB_NAME;
?>
This is assuming you're on the same server and you can access wp-config.php through the file system.
If you're doing this for a plugin, these values are already available. You won't need to include the file again.
You can get all the global constants from wp-config.php simply echo the const like that:
<?php
echo DB_HOST;
echo DB_NAME;
echo DB_USER;
echo DB_PASSWORD;
Here is a function to read all WP DB defines:
function get_wordpress_data() {
$content = #file_get_contents( '../wp-config.php' );
if( ! $content ) {
return false;
}
$params = [
'db_name' => "/define.+?'DB_NAME'.+?'(.*?)'.+/",
'db_user' => "/define.+?'DB_USER'.+?'(.*?)'.+/",
'db_password' => "/define.+?'DB_PASSWORD'.+?'(.*?)'.+/",
'db_host' => "/define.+?'DB_HOST'.+?'(.*?)'.+/",
'table_prefix' => "/\\\$table_prefix.+?'(.+?)'.+/",
];
$return = [];
foreach( $params as $key => $value ) {
$found = preg_match_all( $value, $content, $result );
if( $found ) {
$return[ $key ] = $result[ 1 ][ 0 ];
} else {
$return[ $key ] = false;
}
}
return $return;
}
this returns an array like this:
array (size=5)
'db_name' => string '.........'
'db_user' => string '.........'
'db_password' => string '.........'
'db_host' => string 'localhost'
'table_prefix' => string 'wp_'
If you want to connect to DB, for current versions of PHP, using mysqli extention is recommended (mysql extention is going to deprecate):
require_once ("../wp-config.php"); // path to wp-config depends on your file locatoin
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
Just add required wp-load.php file.
you can use all wordpress functionality like
get_recent_posts() and many more...