I have probleme when i want add array from PDO to contructor of class news :
class News{
protected $erreurs = array(),
$id,
$auteur,
$titre,
$contenu;
public function __News(array $donnees){
$this->hydrate($donnees);
}
public function hydrate(array $donnees)
{
foreach ($donnees as $key => $value)
{
$method = 'set'.ucfirst($key);
if (method_exists($this, $method))
{
$this->$method($value);
}
}
}
Class Manager with function get news by id :
public function getUnique($id){
$id = (int)$id;
$sql = $this->db->prepare('SELECT id, auteur, titre, contenu FROM news WHERE id = ?');
$sql->bindParam('1', $id);
$sql->execute();
$mang = $sql->fetch(PDO::FETCH_ASSOC);
return new News($mang);
}
And index. php
$db = new PDO('mysql:host=localhost;dbname=new', 'root','');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$manager = new Manager($db);
$uniqueNews = $manager->getUnique(2);
echo 'id : '.$uniqueNews->getAuteur();
But i don't know why the value of auteur do not display . If I'm going about this contructor completely wrong, please point me in the right direction. Thanks.
The constructor of a class should be either __construct() or a method named after the class. I prefer the first option. The second option is for legacy code.
class News{
public function __construct(array $donnees){
// This is where your constructor code goes
}
}
Your constructor should be called __construct()
class News{
protected $erreurs = array(),
$id,
$auteur,
$titre,
$contenu;
public function __construct(array $donnees){
$this->hydrate($donnees);
}
}
Related
How to make class structure like PDO or ORM
$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();
OR
$stmt = $pdo->prepare($sql);
$stmt->bindvalue(':u',intval($_SESSION['userId']),PDO::PARAM_INT);
$stmt->execute();
What is returned in to $query or $stmt?
how to design class structure like them?
Thank you
EDIT
$query = DB::table('users')->select('name');
meaning :
function select(){
//
return $this;
}
what's returned in to $query for this structure :
$query->addSelect('age')->get();
PDO is done by returning a new class (PDOStatement) with its own methods (read more about it), but it would be the same as:
<?php
class ClassOne
{
private $connection;
public function __construct($database_stuff)
{
$this->connection = $database_stuff;
}
public function prepare($sql)
{
// Code that does something with the $sql
// Then return a new class
return new ClassTwo($this);
}
}
class ClassTwo
{
private $ClassOne;
public function __construct(ClassOne $Class)
{
$this->ClassOne = $Class;
}
public function execute()
{
// Code that does something with ClassOne
}
}
# Start that initial class
$Class = new ClassOne('database:type;host=example;etc=yadayada');
# Do class one method
$query = $Class->prepare("SELECT * FROM fake_table");
# $query is now ClassTwo, so you do method from ClassTwo
$query->execute();
The ability to chain methods together is achieved because the current method returns the object back in the form of $this:
<?php
class DBClass
{
protected $connection,
$value;
public function __construct($connection)
{
$this->connection = $connection;
}
public function prepare($value)
{
$this->value = $value;
# Return the object
return $this;
}
public function execute()
{
echo $this->value;
# Return the object
return $this;
}
}
$con = new DBClass("login creds");
$con->prepare("update stuff if stuff = 'things'")->execute();
?>
User::updatemain($set, $where);
This gives Fatal error: Using $this when not in object context
My user class extends from Dbase class and here is user class function:
public static function activate($set, $where) {
return $this->updatemain($set, $where);
here is dbase class (some part of):
private function query($sql = null, $params = null) {
if (!empty($sql)) {
$this->_last_statement = $sql;
if ($this->_db_object == null) {
$this->connect();
}
try {
$statement = $this->_db_object->prepare($sql, $this->_driver_options);
$params = Helper::makeArray($params);
$x = 1;
if (count($params)) {
foreach ($params as $param) {
$statement->bindValue($x, $param);
$x++;
}
}
if (!$statement->execute() || $statement->errorCode() != '0000') {
$error = $statement->errorInfo();
throw new PDOException("Database error {$error[0]} : {$error[2]}, driver error code is {$error[1]}");
exit;
}
//echo $sql;
return $statement;
} catch (PDOException $e) {
echo $this->formatException($e);
exit;
}
}
}
public function updatemain($set, $where) {
return $this->query($sql, $params);
}
this is part of Dbase class
You are calling static method so there is no $this in that context.
If you want to call other static method from given class then use self::method() but if you want to call non-static method you've got problem. First you have to create new object.
When you use static methods, you can't use $this inside
public static function activate($set, $where) {
return self::updatemain($set, $where);
}
Or you have to use singelton design
EDIT
Best solution - rewrite your class to one point access to DB object. And create Model classes to DB access. See my example code below:
core AppCore
<?php
class AppCore
{
public static $config = array();
public static $ormInit = false;
public static function init($config)
{
self::$config = array_merge(self::$config, $config);
}
public static function db($table)
{
// ORM - see http://idiorm.readthedocs.org/en/latest
if (!self::$ormInit) {
ORM::configure(self::$config['db']['connection']);
ORM::configure('username', self::$config['db']['username']);
ORM::configure('password', self::$config['db']['password']);
self::$ormInit = true;
}
return ORM::for_table($table);
}
}
User model
<?php
class UserModel
{
const TABLE = 'user';
public static function findById($u_id)
{
$result = AppCore::db(self::TABLE)->where('u_id', $u_id)->find_one();
return $result ? $result->as_array() : null;
}
}
AppCore init section
AppCore::init(array(
'db' => array(
'connection' => "mysql:dbname={$db};host={$host}",
'username' => $user,
'password' => $pass
),
));
i hope it help make your code better
I get this error where I run :
$db = new PDO('mysql:host=localhost;dbname=MYDATABASE', 'root', '');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$Manager = new CompanyManager($db);
$Manager->getList();
ERROR :
Warning: Missing argument 2 for Company::__construct(), called in /.../CompanyManager.class.php on line 53 and defined in /.../Company.class.php on line 17
Here is the part of CompanyManager.class.php :
public function getList()
{
$Company = array();
$q = $this->_db->query('SELECT id, statut, company, activity, source, secteur, comments, offer_date, entry_date, type_ope, gestionnaire, next_step FROM prospect ORDER BY id');
while ($donnees = $q->fetch(PDO::FETCH_ASSOC))
{
$Company[] = new Company($donnees);
}
return $Company;
}
And here is Company.class.php (interesting part) :
<?php
class Company
{
private $_id;
private $_statut;
private $_company;
private $_activity;
private $_source;
private $_secteur;
private $_comments;
private $_offerDate;
private $_entryDate;
private $_typeOpe;
private $_gestionnaire;
private $_nextStep;
public function __construct($id, $statut, $company, $activity, $source, $secteur, $comments, $offerDate, $entryDate, $typeOpe, $gestionnaire, $nextStep)
{
$this->setId($id);
$this->setStatut($statut);
$this->setCompany($company);
$this->setActivity($activity);
$this->setSource($source);
$this->setSecteur($secteur);
$this->setComments($comments);
$this->setOfferDate($offerDate);
$this->setEntryDate($entryDate);
$this->setTypeOpe($typeOpe);
$this->setGestionnaire($gestionnaire);
$this->setNextStep($nextStep);
}
BIG thanks for everyone who gonna try to give me a hand ;-)
public function getList()
{
$Company = array();
$q = $this->_db->query('SELECT id, statut, company, activity, source, secteur, comments, offer_date, entry_date, type_ope, gestionnaire, next_step FROM prospect ORDER BY id');
while ($donnees = $q->fetch(PDO::FETCH_ASSOC))
{
$Company[] = new Company($donnees['id'], $donnees['statut'], $donnees['company'], $donnees['activity'], $donnees['source'], .....);
}
return $Company;
}
Otherwise you can do this
public function __construct(array $data) {
$this->setId($data['id']);
.
.
.
.
}
Well your Company class expects all the parameters in the __construct() parameter list to be passed. None of them are optional.
It looks like you are passing an array to your Company class at the minute, you need to pass each value according to your parameter list.
You have to implicitly pass variables to Company's constructor:
public function getList()
{
$Company = array();
$q = $this->_db->query('SELECT id, statut, company, activity, source, secteur, comments, offer_date, entry_date, type_ope, gestionnaire, next_step FROM prospect ORDER BY id');
while (list($id, $status, $company, /*etc*/) = $q->fetch(PDO::FETCH_ASSOC))
{
$Company[] = new Company($id, $status, $company, /*etc*/);
}
return $Company;
}
I have a class "test" with 2 functions, one to create the prepared statement and one to execute one or more times. The problem is how do i set the binding in the first one and fill in the vars on the other function.
class test {
private static $moduleSql = "SELECT
id,
module
FROM
phs_pages
WHERE
prettyurl = :prettyUrl AND
mainId = :mainId
";
private static function pre() {
$db = Db_Db::getInstance();
self::$preModuleSql = $db->prepare(self::$moduleSql);
self::$preModuleSql->bindParam(':prettyUrl', $prettyUrl);
self::$preModuleSql->bindParam(':mainId', $mainId);
}
private static function getClassByDb($mainId = 0, $id = 0) {
$prettyUrl = self::$parts[$id];
self::$preModuleSql->execute();
self::$preModuleSql->debugDumpParams();
$result = self::$preModuleSql->fetch(PDO::FETCH_ASSOC);
// get lower level classes
if (isset(self::$parts[$id + 1])) {
self::getClassByDb($result['id'], $id + 1);
} else {
return $result;
}
}
}
You donĀ“t need to bind any parameters in your first function, you need to do that in your second function, right before you execute the prepared statement.
Edit: By the way, you can also call execute with an array that contains your parameters as keys and the values you want to send.
There are so many things wrong with this class definition .. ehh.
It should look like this :
class RepositoryException extends Exception{}
interface iRepository
{
public function store( $key , PDOStatement $statement );
public function fetch( $key );
}
class StatementRepository implements iRepository{
protected $_pool = array();
public function store( $key , PDOStatement $statement )
{
$this->_pool[ $key ] = $statement;
}
public function fetch( $key )
{
if ( !array_key_exists( $key , $this->_pool ) ){
throw new RepositoryException(
"Statement with name '$key' does not exist" );
}
return $this->_pool[ $key ];
}
}
$repo = new StatementRepository;
$foo = new Foo( $repo );
$bar = new Bar( $repo );
$db = new PDO('sqlite::memory:');
$statement = $db->prepare( 'SELECT .... ');
$repo->store( 'bljum' , $statement );
This way all the object which have accepted in the constructor an object which implements iRepository can fetch statements by name.
You class should not have more responsibilities then it needs. If it is for storing prepared statements , then it should have nothing to do with binding parameters to them and executing something.
Here is what Foo class would do :
class Foo
{
protected $_repo = null;
public function __construct( iRepository $repo )
{
$this->_repo = $repo;
}
public function ergo( $x , $y )
{
$statement = $this->_repo->fetch('bljum');
//bind values
$statement->execute();
}
}
I am a learner, I have a class db to help me connect and fetch results in mySQL.
$set = $db->get_row("SELECT * FROM users");
echo $set->name;
this way i use echo results outside a class.
Now i have created another class name user and it has this function
public function name() {
global $db;
$set = $db->get_row("SELECT * FROM users");
$this->name = $set->name;
}
after initializing the class user, when i try to echo $user->name i dont get expected results.
Note i have declared above var $name; in class user
I'm pretty concerned by several things I see here
The method name name() is terribly uncommunicative as to what the method is supposed to do. Remember, methods are actions - try to give them some sort of verb in their name.
Usage of global in a class (or even usage of global period) when you should be using aggregation or composition.
You don't show any execution examples, but I can only assume you never actually call User::name(), which is why your test is failing
Here's some code that addresses these concerns.
<?php
class DB
{
/* Your methods and stuff here */
}
class User
{
protected $db;
protected $name;
public function __construct( DB $db )
{
$this->db = $db;
}
public function getName()
{
if ( is_null( $this->name ) )
{
$set = $this->db->get_row( "SELECT * FROM users" );
$this->name = $set->name;
}
return $this->name;
}
}
$db = new DB();
$user = new User( $db );
echo $user->getName();
class DB
{
public function get_row($q)
{
# do query and store in object
return $object;
}
}
class User
{
public $name;
public function __construct()
{
$this->name();
}
public function name() {
global $db;
$set = $db->get_row("SELECT * FROM users");
echo "<pre>".print_r($set)."</pre>"; # make sure $set is returning what you expected.
$this->name = $set->name;
}
}
$db = new DB();
$user = new User();
echo $user->name;
I am very much sorry, i figured out that problem was on my part, i was using cookies and had two cookies set which were giving problems :(