this seems to be a common issue, and I've read a lot about it tried to use 'ini_set' to change time outs and still getting this error after only 5 seconds. below is a sample of my code to show the flow between classes.
the thing that i'm most confused about is that it throws this warning after 5 seconds (even after a page refresh), but it still retrieves the data from the database.
require('../cfg/config.php');
class Process {
/**
* #var PDO
*/
private $conn = null;
/**
* #var PDOException
*/
public $error = null;
private $host = DB_SERVER;
private $user = DB_USER;
private $pass = DB_PASS;
private $db = DB_NAME;
public function __construct() {
ini_set('mysql.connect_timeout', 300);
ini_set('default_socket_timeout', 300);
$this->connect();
}
private function connect() {
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->db;
$options = [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
];
try {
$this->conn = new PDO($dsn, $this->user, $this->pass, $options);
} catch(PDOException $e) {
$this->error = $e->getMessage();
}
return $this->conn;
}
public function query($sql, $params = null) {
preg_match('/SELECT/', $sql) ? $select = true : $select = false;
$connect = $this->conn->getAttribute(PDO::ATTR_CONNECTION_STATUS);
echo "CONNECTION STATUS::: " . $connect;
if($this->error == null) {
$query = $this->conn->prepare($sql);
$query->execute($params);
$query ? (!$select ? $results = true : $results = $query->fetchAll(PDO::FETCH_ASSOC))
: $results = false;
} else {
$results = $this->error;
}
return $results;
}
}
class Arrays {
public $family = [];
/**
* #var \Process
*/
private $db;
public function __construct() {
$this->db = new Process();
}
public function setFamily() {
$a = [];
$sql = "SELECT familyNick, familyName FROM budget.family ORDER BY familyOrder";
$query = $this->db->query($sql);
if($query != false && is_array($query)) {
foreach($query as $k => $v) {
$a[$v['familyNick']] = $v['familyName'];
}
}
$this->family = $a;
}
/**
* #return array
*/
public function getFamily() {
if(empty($this->family) || !isset($this->family)) {
$this->setFamily();
}
return $this->family;
}
}
class Options {
public $family = [];
/**
* #var \Arrays
*/
private $arrays;
public function __construct() {
$this->arrays = new Arrays();
}
public function setFamily() {
$this->family = $this->arrays->getFamily();
}
public function getFamilyOptions() {
if(empty($this->family)) {
$this->setFamily();
}
$options = [];
foreach($this->family as $famNick => $famName) {
$options[] = "<option class='family' value='$famNick'>" . $famName . "</option>";
}
return $options;
}
}
$test = new Options();
$family = $test->getFamilyOptions();
var_dump($family);
i'm certain there are various design flaws to this code. i'm just concerned about the PDO warning at this point.
for what i was trying to accomplish simply removing
ATTR_PERSISTENT => true
from the option array did the trick!
Related
This question already has an answer here:
How to use PDO connection in other classes?
(1 answer)
Closed 2 years ago.
I got this PDO database class
class clsDatabase{
// db settings
private $host = 'localhost';
private $user = 'test';
private $dbname = 'test';
private $pass = 'test1';
private $dbh;
private $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,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
);
// Create a new PDO instanace
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}
// Catch any errors
catch(PDOException $e){
$this->error = $e->getMessage();
echo $this->error;
exit;
}
}
public function query($query){
$this->stmt = $this->dbh->prepare($query);
}
}
I try to seperate my code in different classes, for example i got a clsDBUser which is connected to the clsUserController. I do this so i know what class uses what database code. My clsDBUser class looks like this
class clsDBUser extends clsDatabase {
// construct
public function __construct() {
parent::__construct();
}
// get users
public function getUsers($users_id){
$query = "
SELECT
email
FROM
users
WHERE
users_id = :users_id
";
$this->query($query);
$this->bind(':users_id', $users_id);
if($row = $this->single()){
$this->close();
return $row;
}
$this->close();
return false;
}
}
I am wondering if this is the way to go or am i creating a new database connection in every class right now? Because normally in PHP4 (yes i know old) i can't recognize i had to make a new database connection every time.
Do i need to improve this, how do i need to improve this?
You should take the road shown in the mr.void's answer. In short:
get rid of clsDatabase.
Create an instance of PDO.
pass it into clsDBLogin's property like it shown in mr.void's answer.
Then use this pdo instance in the form of $this->db->prepare() and so on
So it should be like
class clsDBLogin
{
public function __construct($db)
{
$this->db = $db;
}
public function validateLogin($email)
{
$email = trim($email);
// Check user in db to start verification
$query = 'SELECT * FROM users u, users_info ui
WHERE u.users_id = ui.users_id AND u.email = ?';
$stmt = $this->db->prepare($query);
$stmt->execute([$email]);
return $stmt->fetch();
}
}
$dsn = 'mysql: host=localhost;dbname=test;charset=utf8';
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
// Create a new PDO instanace
$pdo = new PDO($dsn, $this->user, $this->pass, $options);
$DBLogin = new clsDBLogin($pdo);
$user = $DBLogin->validateLogin($email);
Hey i would do Something like this
class DB {
// connectionStuff goes Here
}
class Model {
private $db
public function __construct($db) {
$this->db = $db;
}
}
Use:
$db = new DB("your connection stuff goes here");
$model = new Model($db);
$userModel = new UserModel($db);
$anotherModel = new AnotherModel($db);
Rebuild:
clsDB class with connection stuff only
class clsDB{
// db settings
private $host = 'localhost';
private $user = 'test';
private $dbname = 'test';
private $pass = 'test';
private $dbh;
private $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,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
);
// Create a new PDO instanace
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}
// Catch any errors
catch(PDOException $e){
$this->error = $e->getMessage();
echo $this->error;
exit;
}
}
}
clsDBLogin:
class clsDBLogin{
private $db;
public function __construct($db) {
$this->db = $db;
}
}
In index.php i do:
$clsDB = new clsDB();
$clsDBLogin = new clsDBLogin($clsDB);
In clsDBLogin i would do:
public function validateLogin($email){
$email = str_replace(' ', '', $email);
$email = strtolower($email);
// Check user in db to start verification
$query = '
SELECT
u.*, ui.*
FROM
users as u,
users_info as ui
WHERE
u.users_id = ui.users_id
AND
u.email = :email
';
$this->db->prepare($query);
$this->db->bindValue(':email', $email, PDO::PARAM_STR);
if($this->db->execute()){
if($row = $this->db->fetch(PDO::FETCH_ASSOC)){
return $row;
}
}
}
There are three layer here:
database connector: you can use pure PDO for this or a database abstraction layer library (Doctrine DBAL)
repository of entities: in other words, some kind of ORM. Doctrine provides advanced ORM functionality. Of course, you can write your own lightweight solution.
entity: can be a simple CRUD, an ActiveRecord or any other object representation of a logical record.
When we do this manually... First, don't extend these from each other. Generally: never extend a different layer from an other. Use Dependency Injection (DI) instead.
It's a very simple case of DI when you pass all the specific information (dependencies) as constructor parameters. My active-object-like example Entity just knows how an entity should be behave in general (at a key in a repository). For simplicity, I use raw SQL.
Repository class:
class Repository {
private $oPDO;
private $tableName;
private $keyFieldName;
public function __construct($oPDO, $tableName, $keyFieldName) {
$this->oPDO = $oPDO;
$this->tableName = $tableName;
$this->keyFieldName = $keyFieldName;
}
public function getPDO() {
return $this->oPDO;
}
public function getTableName() {
return $this->tableName;
}
public function getKeyFieldName() {
return $this->keyFieldName;
}
public function getEntity($id) {
return new Entity($this, $id);
}
public function createEntity() {
return new Entity($this, null);
}
}
Entity class:
class Entity implements ArrayAccess {
private $oRepository;
private $id;
private $record = null;
public function __construct($oRepository, $id) {
$this->oRepository = $oRepository;
$this->id = $id;
}
public function load($reload = false) {
if (!$this->record && !$this->id) {
return false;
}
if (!$reload && !is_null($this->record)) {
return true;
}
$quotedTableName = $this->quoteIdentifier($this->oRepository->getTableName());
$quotedKeyFieldName = $this->quoteIdentifier($this->oRepository->getKeyFieldName());
$selectSql = "SELECT * FROM {$quotedTableName} WHERE {$quotedKeyFieldName} = ?";
$oStatement = $this->oRepository->getPDO()->prepare($selectSql);
$this->bindParam($oStatement, 1, $this->id);
$oStatement->execute();
$result = $oStatement->fetch(PDO::FETCH_ASSOC);
if ($result === false || is_null($result)) {
return false;
}
$this->record = $result;
return true;
}
public function save() {
$oPDO = $this->oRepository->getPDO();
$tableName = $this->oRepository->getTableName();
$keyFieldName = $this->oRepository->getKeyFieldName();
$quotedTableName = $this->quoteIdentifier($tableName);
$quotedKeyFieldName = $this->quoteIdentifier($keyFieldName);
if (is_null($this->id)) {
$insertSql = "INSERT INTO {$quotedTableName} (";
$insertSql .= implode(", ", array_map([$this, "quoteIdentifier"], array_keys($this->record)));
$insertSql .= ") VALUES (";
$insertSql .= implode(", ", array_fill(0, count($this->record), "?"));
$insertSql .= ")";
$oStatement = $oPDO->prepare($insertSql);
$p = 1;
foreach ($this->record as $fieldName => $value) {
$this->bindParam($oStatement, $p, $value);
$p++;
}
if ($oStatement->execute()) {
$this->id = $oPDO->lastInsertId();
return true;
} else {
return false;
}
} else {
$updateSql = "UPDATE {$quotedTableName} SET ";
$updateSql .= implode(" = ?, ", array_map([$this, "quoteIdentifier"], array_keys($this->record)));
$updateSql .= " = ? WHERE {$quotedKeyFieldName} = ?";
$oStatement = $oPDO->prepare($updateSql);
$p = 1;
foreach ($this->record as $fieldName => $value) {
$this->bindParam($oStatement, $p, $value);
$p++;
}
$this->bindParam($oStatement, $p, $this->id);
if ($oStatement->execute()) {
if (isset($this->record[$keyFieldName])) {
$this->id = $this->record[$keyFieldName];
}
return true;
} else {
return false;
}
}
}
public function isExisting($reload = false) {
if (!$this->record && !$this->id) {
return false;
}
if (!$reload && !is_null($this->record)) {
return true;
}
$quotedTableName = $this->quoteIdentifier($this->oRepository->getTableName());
$quotedKeyFieldName = $this->quoteIdentifier($this->oRepository->getKeyFieldName());
$selectSql = "SELECT 1 FROM {$quotedTableName} WHERE {$quotedKeyFieldName} = ?";
$oStatement = $this->oRepository->getPDO()->prepare($selectSql);
$oStatement->bindParam(1, $this->id);
$oStatement->execute();
$result = $oStatement->fetch(PDO::FETCH_ASSOC);
if ($result === false || is_null($result)) {
return false;
}
return true;
}
public function getId() {
return $this->id;
}
public function getRecord() {
$this->load();
return $this->record;
}
public function offsetExists($offset) {
$this->load();
return isset($this->record[$offset]);
}
public function offsetGet($offset) {
$this->load();
return $this->record[$offset];
}
public function offsetSet($offset, $value) {
$this->load();
$this->record[$offset] = $value;
}
public function offsetUnset($offset) {
$this->load();
$this->record[$offset] = null;
}
private function quoteIdentifier($name) {
return "`" . str_replace("`", "``", $name) . "`";
}
private function bindParam($oStatement, $key, $value) {
$oStatement->bindParam($key, $value);
}
}
Usage:
$oRepo = new Repository($oPDO, "user", "user_id");
var_dump($oRepo->getEntity(2345235)->isExisting());
$oSameUser = $oRepo->getEntity(1);
var_dump($oSameUser->isExisting());
var_dump($oSameUser->getRecord());
$oNewUser = $oRepo->createEntity();
$oNewUser["username"] = "smith.john";
$oNewUser["password"] = password_hash("ihatesingletons", PASSWORD_DEFAULT);
$oNewUser["name"] = "John Smith";
$oNewUser->save();
$oNewUser["name"] = "John Jack Smith";
$oNewUser->save();
Of course, you can extend a MoreConcreteRepository from Repository and MoreConcreteEntity from Entity with specific behavior.
Simply don't extend an entity (clsDBUser) from a connection class (clsDatabase).
Use a singleton (or something more advanced pattern) for clsDatabase.
For example:
class clsDatabase {
static private $instance = null;
// some other private fields
private function __construct(/* parameters*/) {
// do it
}
public static function instance() {
if (is_null(self::$instance)) {
self::$instance = new self(/* pass any parameters */);
}
return self::$instance;
}
public function queryRow($query) {
$oStatement = $this->dbh->prepare($query);
// ...
return $row;
}
}
class clsDBUser {
public function getUser($id) {
$query = "...";
return $clsDatabase::instance()->queryRow($query);
}
}
While trying to connect through PHP it displays
Warning: mysqli_connect(): (HY000/1044): Access denied for user ''#'localhost' to database 'bookedscheduler' in C:\wamp\www\booked\lib\Database\MySQL\MySqlConnection.php on line 52
Warning: mysqli_select_db() expects parameter 1 to be mysqli, boolean given in C:\wamp\www\booked\lib\Database\MySQL\MySqlConnection.php on line 53
Warning: mysqli_set_charset() expects parameter 1 to be mysqli, boolean given in C:\wamp\www\booked\lib\Database\MySQL\MySqlConnection.php on line 54
Cannot modify header information - headers already sent by (output started at C:\wamp\www\booked\lib\Database\MySQL\MySqlConnection.php:53) in C:\wamp\www\booked\Pages\Page.php on line 138
My config.php
database connection
$conf['settings']['database']['type'] = 'mysql';
$conf['settings']['database']['user'] = 'booked_user';
$conf['settings']['database']['password'] = '';
$conf['settings']['database']['hostspec'] = '127.0.0.1';
$conf['settings']['database']['name'] = 'bookedscheduler';
Mysqlconnection.php file
class MySqlConnection implements IDbConnection
{
private $_dbUser = '';
private $_dbPassword = '';
private $_hostSpec = '';
private $_dbName = '';
private $_db = null;
private $_connected = false;
/**
* #param string $dbUser
* #param string $dbPassword
* #param string $hostSpec
* #param string $dbName
*/
public function __construct($dbUser, $dbPassword, $hostSpec, $dbName)
{
$this->_dbUser = $dbUser;
$this->_dbPassword = $dbPassword;
$this->_hostSpec = $hostSpec;
$this->_dbName = $dbName;
}
public function Connect()
{
if ($this->_connected && !is_null($this->_db))
{
return;
}
$this->_db = mysqli_connect($this->_hostSpec, $this->_dbUser, $this->_dbPassword,$this->_dbName);
$selected = mysqli_select_db($this->_db, $this->_dbName);
mysqli_set_charset($this->_db, 'utf8');
if (!$this->_db || !$selected)
{
throw new Exception("Error connecting to database\nError: " . mysql_error());
Log::Error("Error connecting to database\n%s", mysql_error());
}
$this->_connected = true;
}
public function Disconnect()
{
mysqli_close($this->_db);
$this->_db = null;
$this->_connected = false;
}
public function Query(ISqlCommand $sqlCommand)
{
mysqli_set_charset($this->_db, 'utf8');
$mysqlCommand = new MySqlCommandAdapter($sqlCommand, $this->_db);
Log::Sql('MySql Query: ' . str_replace('%', '%%', $mysqlCommand->GetQuery()));
$result = mysqli_query($this->_db, $mysqlCommand->GetQuery());
$this->_handleError($result);
return new MySqlReader($result);
}
public function LimitQuery(ISqlCommand $command, $limit, $offset = 0)
{
return $this->Query(new MySqlLimitCommand($command, $limit, $offset));
}
public function Execute(ISqlCommand $sqlCommand)
{
mysqli_set_charset($this->_db, 'utf8');
$mysqlCommand = new MySqlCommandAdapter($sqlCommand, $this->_db);
Log::Sql('MySql Execute: ' . str_replace('%', '%%', $mysqlCommand->GetQuery()));
$result = mysqli_query($this->_db, $mysqlCommand->GetQuery());
$this->_handleError($result);
}
public function GetLastInsertId()
{
return mysqli_insert_id($this->_db);
}
private function _handleError($result, $sqlCommand = null)
{
if (!$result)
{
if ($sqlCommand != null)
{
echo $sqlCommand->GetQuery();
}
throw new Exception('There was an error executing your query\n' . mysql_error());
Log::Error("Error executing MySQL query %s", mysql_error());
}
return false;
}
}
class MySqlLimitCommand extends SqlCommand
{
/**
* #var \ISqlCommand
*/
private $baseCommand;
private $limit;
private $offset;
public function __construct(ISqlCommand $baseCommand, $limit, $offset)
{
parent::__construct();
$this->baseCommand = $baseCommand;
$this->limit = $limit;
$this->offset = $offset;
$this->Parameters = $baseCommand->Parameters;
}
public function GetQuery()
{
return $this->baseCommand->GetQuery() . sprintf(" LIMIT %s OFFSET %s", $this->limit, $this->offset);
}
}
?>
Please someone guide me in this regard
It is very easy and I am providing you a tested answer, first you need to build the Database class as seen below, you need to put it in a file and include it from your homepage (might be the index.php page). Then, you need to initiate an instance of your class from the homepage to connect to the database, the code is very well explained in details in this great article: www.muwakaba.com/php-database-connection
<?php
// Class definition
class Database{
// The constructor function
public function __construct(){
// The properties
$this->host = "your_DB_host_address";
$this->login = "your_DB_login_name";
$this->password = "your_DB_password";
$this->name = "your_DB_name";
// The methods
$this->connect();
$this->select();
}
// The connect function
private function connect(){
$this->connection = mysql_connect($this->host, $this->login, $this->password) or die("Sorry! Cannot connect to the database");
}
// The select function
private function select(){
mysql_select_db($this->name, $this->connection);
}
}
?>
I use of this mvc. (here is the documentation). Now I want to create a module for connect to database and run the query. but there is a error:
Fatal error: Cannot access self:: when no class scope is active in {address(in db.class.php)}
What is the problem ??
db.class.php (in the model folder)
<?php
class db{
/*** Declare instance ***/
private static $instance = NULL;
/*
* #return object (PDO)
*
* #access public
*/
public static function getInstance() {
if (!self::$instance) {
function dataQuery($query, $params) {
// what kind of query is this?
$queryType = explode(' ', $query);
// establish database connection
try {
self::$instance = new PDO('mysql:host=localhost;dbname=spy', USER, PASS);
self::$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo $e->getMessage();
$errorCode = $e->getCode();
}
// run query
try {
$queryResults = self::$instance->prepare($query);
$queryResults->execute($params);
if($queryResults != null && 'SELECT' == $queryType[0]) {
$results = $queryResults->fetchAll(PDO::FETCH_ASSOC);
return $results;
}
$queryResults = null; // first of the two steps to properly close
$dbh = null; // second step tp close the connection
}
catch(PDOException $e) {
$errorMsg = $e->getMessage();
echo $errorMsg.'<br>';
}
}
}
return self::$instance;
}
} /*** end of class ***/
?>
init.php (in the includes )
<?php
function __autoload($class_name) {
$filename = strtolower($class_name) . '.class.php';
$file = __SITE_PATH . '/model/' . $filename;
if (file_exists($file) == false)
{
return false;
}
include ($file);
}
/*** a new registry object ***/
$registry = new registry;
/*** create the database registry object ***/
$registry->db = db::getInstance();
?>
index.php: (in the controller folder)
<?php
Class indexController Extends baseController {
public function index() {
error_reporting(E_ALL);
ini_set('display_errors', 1);
define('USER', 'root');
define('PASS', '');
function findKitByMfgPrice($mfg, $price) {
$query = "SELECT * FROM `test` WHERE `prod_name` LIKE ? AND `prod_price` > ?";
$params = array($mfg, $price);
$results = dataQuery($query, $params);
return $results;
}
$mfg = '%Mobeius%';
$price = 34.95;
$kitsByMfgPrice = findKitByMfgPrice($mfg, $price);
echo '<pre>';
$welcome = $kitsByMfgPrice;
/*** set a template variable ***/
$this->registry->template->welcome = $welcome;
/*** load the index template ***/
$this->registry->template->show('index1');
}
?>
Your database should be used this way :
db.php :
class db{
/*** Declare instance ***/
private static $instance = NULL;
/*
* #return object (PDO)
*
* #access public
*/
public static function getInstance() {
if (!self::$instance) {
// establish database connection
try {
self::$instance = new PDO('mysql:host=localhost;dbname=spy', USER, PASS);
self::$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo $e->getMessage();
$errorCode = $e->getCode();
}
}
return self::$instance;
}
public static function dataQuery($query, $params) {
// what kind of query is this?
$queryType = explode(' ', $query);
// run query
try {
$queryResults = self::getInstance()->prepare($query);
$queryResults->execute($params);
if($queryResults != null && 'SELECT' == $queryType[0]) {
$results = $queryResults->fetchAll(PDO::FETCH_ASSOC);
return $results;
}
$queryResults = null; // first of the two steps to properly close
$dbh = null; // second step tp close the connection
}
catch(PDOException $e) {
$errorMsg = $e->getMessage();
echo $errorMsg.'<br>';
}
} /*** end of class ***/
and to use it, in your index :
function findKitByMfgPrice($mfg, $price) {
$query = "SELECT * FROM `test` WHERE `prod_name` LIKE ? AND `prod_price` > ?";
$params = array($mfg, $price);
$results = db::dataQuery($query, $params);
return $results;
}
this should be a good start. But It still looks strange... the dataQuery methods is misplaced, it should not be part of the db class, it should be a local method of your index I think... Must think about it...
I have a:
class Person
{
public $data;
public function __construct($name) {
$database = new Database;
$database->prepare('SELECT * FROM persons where name = :name');
$database->bindParam(':name', $name);
$database->execute();
$this->data = $database->fetch();
}
}
and i´m creating persons like this:
$jim = new Person('Jim');
$mike = new Person('Mike');
and this is my database class
class Database
{
private $host = 'localhost';
private $user = 'test';
private $pass = '123';
private $dbname = 'test';
private $dbh;
private $error;
private $stmt;
public function __construct()
{
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}
catch(PDOException $e){
$this->error = $e->getMessage();
echo $this->error;
}
}
public function prepare($query)
{
$this->stmt = $this->dbh->prepare($query);
}
public function bindParam($key, $val)
{
$this->stmt->bindParam($key, $val);
}
public function execute()
{
$this->stmt->execute();
}
public function fetch()
{
return $this->stmt->fetch(PDO::FETCH_ASSOC);
}
}
I´m getting this message very often
Warning: PDO::__construct(): MySQL server has gone away
I want to confirm if this approach is correct. calling the database in the constructor?
How can i know if the created person exists (i mean exist in the database)
should i do something like this?
$jim = new Person('Jim');
if($jim->data) {
echo 'person exists in the db';
}
thank you
i want to crete a class that will contain various general variables and functions to be used throughout the website. One of these things will be a database connection. I am trying the following code:
class Sys {
public $dbc = new mysqli('localhost', 'user', 'pass', 'db');
$dbc->query("SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'");
}
$system = new Sys;
It is giving me a syntax error in the first line of the class... What am i doing wrong?
Thanks
you should do things like this in the constructor. You can only set primitives in the initial declaration. Also you need braces when creating the object.
class Sys {
private $dbc;
private $someInteger = 4; // you can do this
private $someArray = array(); // and this.
public function __construct()
{
$this->dbc = new mysqli('localhost', 'user', 'pass', 'db');
$this->dbc->query("SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'");
}
public function getDbc()
{
return $this->dbc;
}
}
$system = new Sys();
//$system->getDbc()->soSomethingWithMyDb();
i would advise you to read up on using objects: http://php.net/manual/en/language.types.object.php
You should just declare a public $dbc.
And then have a constructor function function __construct() { ...... } where you initialize it/ set it up.
class Sys {
public $dbc;
function __construct() {
$this->dbc = new mysqli('localhost', 'user', 'pass', 'db');
$this->dbc->query("SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'");
}
}
$system = new Sys;
class Sys {
var $mysqli;
function DB($database,$server,$user,$pass) {
$this->mysqli = mysqli_connect($server, $user, $pass, $base) or die('Server connection not possible. '. mysqli_connect_error());
}
}
include("db.class.mysqli.php"); // db handler class
// Open the base (construct the object):
$db = new Sys(DB_NAME, SERVER_NAME, USER_NAME, PASSWORD);
This is how I do it
check out the use of magic methods http://php.net/manual/en/language.oop5.magic.php in php - as mentioned above the __construct method is needed for your class to work. Below is an example from Peter Lavin's book Object Oriented PHP http://objectorientedphp.com/ in chapter 9.
class MySQLConnect {
// Data Members
private $connection;
private static $instances = 0;
// Constructor
public function __construct($hostname, $username, $password) {
if(MySQLConnect::$instances == 0) {
$this->connection = new mysqli($hostname, $username, $password);
// Check for Errors then report them
if ($this->connection->connect_error) {
die("Connect Error ($this->connection->connect_errno) $this->connection->connect_error");
}
// Set the Class variable $instances to 1
MySQLConnect::$instances = 1;
} else {
$msg = "There's another instance the MySQLConnect Class with a connect open already. Close it";
die($msg);
}
}
}
Try this:
$db = new DB;
$link = $db->connect()->getLink();
class DB {
public $connection = array();
public function __construct() {
return $this;
}
public function connect($host=null, $user=null, $pass=null, $database=null) {
$this->connection = new Connection($host, $user, $pass, $database);
$this->connection->connect();
$this->link = $this->connection->getLink();
if ($this->connection->ping()) {
if (!is_null($database)) {
if (!$this->connection->databaseConnect($database)) {
throw new\Exception('Unable to connect to the server.');
}
}
}else{
throw new \Exception('Unable to connect to the server.');
}
return $this;
}
public function getLink() {
return $this->link;
}
}
class Connection {
protected $chost='localhost';
protected $cuser='guest';
protected $cpass='password';
protected $cdatabase='PROFORDABLE';
function __construct($host=null, $user=null, $pass=null, $database=null) {
$host = !is_null($host) ? $host : $this->chost;
$user = !is_null($user) ? $user : $this->cuser;
$password = !is_null($pass) ? $pass : $this->cpass;
$database = !is_null($database) ? $database : $this->cdatabase;
$this->set('host', $host)->set('user', $user)->set('password', $password)->set('database', $database);
return $this;
}
public function connect() {
$link = mysqli_connect($this->host->getHost(), $this->user->getUser(), $this->password->getPassword());
if (!is_object($link)) {
throw new \Exception("An error has occurred while connecting to the server.");
}
$this->link = $link;
}
public function databaseConnect($database) {
if (!mysqli_select_db($this->getLink(), $database)) {
throw new \Exception("Unable to select the database.");
}
}
public function getLink() {
return $this->link;
}
public function ping() {
if (mysqli_ping($this->link)) {
return TRUE;
}
return FALSE;
}
public function set($name, $param) {
if (!isset($name) || !isset($param)) return $this;
$class = __NAMESPACE__.'\\'.ucwords($name);
$this->$name = new $class($param);
return $this;
}
public function get($name) {
$getfunc = 'get'.ucwords($name);
return $this->$name->$getFunc();
}
}
class Host {
public function __construct($host) {
$this->setHost($host);
}
public function setHost($host) {
$this->host = $host;
}
public function getHost() {
return $this->host;
}
}
class User {
public function __construct($user) {
$this->setUser($user);
}
public function setUser($user) {
$this->user = $user;
}
public function getUser() {
return $this->user;
}
}
class Password {
public function __construct($password) {
$this->setPassword($password);
}
public function setPassword($password) {
$this->password = $password;
}
public function getPassword() {
return $this->password;
}
public function sha($value) {
return sha1($value);
}
}
class guestPassword extends Password {
const PASSWORD='password';
public function __construct() {
return PASSWORD;
}
}
class Database {
public function __construct($database) {
$this->setDatabase($database);
}
public function setDatabase($database) {
$this->database = $database;
}
public function getDatabase() {
return $this->database;
}
}
class Query {
}
//Create mysql.php and paste following code
<?php
class MySQL {
private $set_host;
private $set_username;
private $set_password;
private $set_database;
public function __Construct($set_host, $set_username, $set_password) {
$this->host = $set_host;
$this->username = $set_username;
$this->password = $set_password;
$con = mysql_connect($this->host, $this->username, $this->password);
if (!$con) {
die("Couldn't connect to the server");
}
}
//end of __construct
//connect to database
public function Database($set_database) {
$this->database = $set_database;
mysql_query("set character_set_server='utf8'");
mysql_query("set names 'utf8'");
mysql_select_db($this->database) or die("Unable to select database");
}
//fetch data from any table
public function fetch_data($sql) {
$this->sql = $sql;
$query = mysql_query($this->sql);
$result = array();
while ($record = mysql_fetch_array($query)) {
$result[] = $record;
}
return $result;
}
//fetch all columns from any table to be used for INSERT INTO.
public function get_all_columns($table_name) {
$this->table_name = $table_name;
$sql = "SHOW COLUMNS FROM $this->table_name";
$result = mysql_query($sql);
while ($record = mysql_fetch_array($result)) {
$fields[] = $record['0'];
}
$val = '';
foreach ($fields as $value) {
$val .= $value . ',';
}
$vals = rtrim($val, ',');
return $vals;
}
//insert data to any table by $_POST or set of variables separated by ,
public function insert_data($tbl_name, $tbl_value) {
$this->tbl_name = $tbl_name;
$this->tbl_value = $tbl_value;
//use mysql_real_escape_string($tbl_value) to clean & insert data.
$this->tbl_col = $this->get_all_columns($this->tbl_name);
$sql = "INSERT INTO $this->tbl_name ($this->tbl_col) VALUES ($this->tbl_value)";
$query_result = mysql_query($sql);
}
//end of insert data
public function delete_data($del_id, $table_name) {
$this->del_id = $del_id;
$this->table_name = $table_name;
if (isset($this->del_id) && is_numeric($this->del_id) && !empty($this->del_id)) {
$sql = "DELETE FROM $this->table_name WHERE id=$this->del_id LIMIT 1";
$del_result = mysql_query($sql);
$aff_row = mysql_affected_rows();
return $aff_row;
}
}
}
// class ends here
//call class to connect to server and db as well.
$connect = new MySQL('localhost', 'root', '');
$connect->Database('db_name');
?>
//include file mysql.php and call your class object as :
//fetching data from any table use :
$variable = $connect->fetch_data("SELECT * FROM table_name");
for($i=0;$i<count($variable);$i++){
$result = $variable[$i]['col_name'];
}
//insert INTO values in any table
$result = $connect->insert_data($tbl_name, $tbl_value);
if($result)
echo 'inserted';
else{
echo 'failed';
}
//delete record from any table
$result = $connect->delete_data($del_id, $table_name)
You can use a wonderful class ezSQL