I'm a new with OOP model in PHP. I has been trying to retrieve data from database but something related to private makes me stuck.
This is my code.
<?php
require ("UserData.php");
class Database{
public function getUser($sql){
include ("includes/connect.php");
$statement = $conn->prepare ($sql);
$statement->execute();
while ($row = $statement->fetch()) {
$dataSet[] = new UserData($row);
}
if (!empty($dataSet)) {
return $dataSet;
}else{
die();
}
}
}
?>
the second file
<?php
class UserData
{
private $user_id, $phone,$name,$address;
public function _construct($dbrow){
$this->user_id = $dbrow['user_id'];
$this->name = $dbrow['name'];
$this->phone = $dbrow['phone'];
$this->address = $dbrow['address'];
}
public function getUserId(){
return $this->user_id;
}
public function getUserName(){
return $this->name;
}
public function getUserPhone(){
return $this->phone;
}
public function getUserAddress(){
return $this->address;
}
}
?>
and the last one
<?php require ("Database.php"); ?>
<html>
<head>
<title>OOP</title>
</head>
<body>
<?php
include("includes/connect.php");
$db = new Database();
$dataSet = $db -> getUser ("SELECT * from user");
if ($dataSet) {
foreach ($dataSet as $data) {
echo "<p>";
echo "ID" .$data->getUserId()."<br />";
echo "Name" .$data->getUserName()."<br />";
echo "Phone" .$data->getUserPhone()."<br />";
echo "Address" .$data->getUserAddress()."<br />";
echo "</p>";
}
}else{
echo "no result found";
}
?>
</body>
</html>
Well, I tried to var_dump the dataSet but the error shows up.
array(2) { [0]=> object(UserData)#5 (4) {
["user_id":"UserData":private]=> NULL ["phone":"UserData":private]=>
NULL ["name":"UserData":private]=> NULL
["address":"UserData":private]=> NULL } [1]=> object(UserData)#6 (4) {
["user_id":"UserData":private]=> NULL ["phone":"UserData":private]=>
NULL ["name":"UserData":private]=> NULL
["address":"UserData":private]=> NULL } }
So can anyone show me which spots make the code dump?
Everything is okay except this line,
public function _construct($dbrow){ ...
^^^^^^^^^^ it should be double underscore, not single
Your constructor method in UserData class is wrong. It should be,
public function __construct($dbrow){ ...
In PHP 5.6.0+, you can use the magic mathod __debugInfo()
class UserData
{
public function __debugInfo() {
return ['user_id' => $this->user_id, 'phone' => $this->phone, 'name' => $this->name, 'address' => $this->address];
}
}
or makes variables public, which is not intend when you have methods like getUserId
or create method to dump like:
class UserData
{
public function dump() {
var_dump($this);
}
}
btw in class Database method getUser you include all the time when method is called, quick fix: use require_once instead of include, better will be to call include/require/require_once outside of class
Related
I've written a class which in the construct accesses the db and gets a list of names. These names go into an associative array e.g. ('name' => 'id').
i.e. the point is to pass in the name to get back an ID:
$id = names::nameToId('some name');
print $id;
// prints int
The problem is when I try and return the array from the construct I get an error:
Notice: Undefined variable: nameArray in (etc)
Here is the code so far:
class nameToId {
public $nameArray;
private $mysqli;
public function __construct($mysqli) {
...
while($row = mysqli_fetch_assoc($res)) {
$nameArray[$row['name']] = $row['id'];
}
return $nameArray;
}
static public function nameToId($name) {
$nameId = $nameArray[$name];
return $nameId;
}
}
$namesToId = new nameToId($mysqli);
$nameId = $namesToId::nameToId('some name');
echo $nameId;
Why doesn't $nameArray get passed to nameToId()? I'm new to classes, and I thought by declaring $nameArray as public when I first create the class that it would make it available. I have also tried to make it global even though I know that is not good form but even still it didn't work.
Because you cannot return anything from a constructor. Any return value is being ignored and just goes into the aether. $nameArray is a local variable and is not shared in any other scope, i.e. you can't access it in nameToId. Further, since nameToId is static, it won't have access to data from any non-static methods like __construct to begin with.
You probably want something like this:
class nameToId {
public $nameArray;
private $mysqli;
public function __construct($mysqli) {
...
while ($row = mysqli_fetch_assoc($res)) {
$this->nameArray[$row['name']] = $row['id'];
}
}
public function nameToId($name) {
return $this->nameArray[$name];
}
}
$namesToId = new nameToId($mysqli);
echo $namesToId->nameToId('some name');
Fix your code:
class nameToId {
public static $nameArray;
private $mysqli;
public function __construct($mysqli) {
$this->mysqli = $mysqli;
$sql = 'SELECT id, name FROM teams';
$res = mysqli_query($this->mysqli,$sql);
while($row = mysqli_fetch_assoc($res)) {
self::$nameArray[$row['name']] = $row['id'];
}
}
static public function nameToId($name) {
$nameId = self::$nameArray[$name];
return $nameId;
}
}
$namesToId = new nameToId($mysqli);
$nameId = $namesToId::nameToId('some name');
echo $nameId;
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
Recently, I've been wanting to implement the Facebook SDK for PHP in my CodeIgniter project.
Facebook sdk can be slooooow, that's why I want to store a class instance containing gathered fb & fb user details in the user session.
When I store the class instance, I can use it later on as long as I don't refresh or redirect.
When I do redirect, the value is unset...
I've read about using serialize and unserialize (for global PHP sessions), but it didn't help in this situation.
This is the fb class:
class FBClass {
protected $FB = false;
protected $FBUser = false;
protected $FBUserProfile = false;
protected $FBUserEmail = false;
protected $loggedIn = false;
protected $config = array(
'appId' => '007',
'secret' => '911',
'cookie' => true,
'fileUpload' => false,
'allowSignedRequest' => false
);
protected $params = array(
'client_id' => '007',
'scope' => 'email'
);
function __construct() {
if (!$this->FB) {
$this->FB = new Facebook($this->config);
}
}
public function isLoggedIn() {
return $this->loggedIn;
}
public function getLoginUrl() {
$this->FB->getLoginUrl($this->params);
}
public function getUser() {
if (!$this->FBUser) {
$this->FBUser = $this->FB->getUser();
}
return $this->FBUser;
}
public function getUserProfile() {
if (!$this->FBUserProfile) {
$this->FBUserProfile = $this->FB->api('/me','GET');
}
if ($this->FBUserProfile && !$this->FBUserEmail) {
$emailArray = $this->FB->api('/me?fields=email');
$this->FBUserEmail = array_key_exists('email', $emailArray) ? $emailArray['email'] : 'Onbekend';
$this->loggedIn = true;
}
return $this->FBUserProfile;
}
public function getUserFullName() {
return $this->FBUserProfile['name'];
}
public function getUserAlias() {
return $this->FBUserProfile['username'];
}
public function getUserEmail() {
return $this->FBUserEmail;
}
public function getUserFirstName() {
return $this->FBUserProfile['first_name'];
}
public function getUserLastName() {
return $this->FBUserProfile['last_name'];
}
public function getUserId() {
return $this->FBUserProfile['id'];
}
}
In my controller, I store or retrieve my FBClass instance like this:
public function checkFacebookState() {
if (!$this->session->userdata('fb')) {
$fbSes = new FBClass();
$this->session->set_userdata('fb', serialize($fbSes));
} else {
$fbSes = unserialize($this->session->userdata('fb'));
}
}
Storing strings in the session does work.
I know PHP is not OO, that's why I'm looking for an easy alternative.
Any ideas?
In order for you to save your instance in a session, there is no problem whether you serialize it first or not.
Take the following example for instance.
create a library test in your application/library folder:
class Test {
public $testProp;
public function __construct() {
$this->testProp = 'testing';
}
}
then in your controller write the following:
class Welcome extends CI_Controller {
public function index()
{
$this->load->library('test');
$this->session->set_userdata('someIns', $this->test);
$this->load->view('welcome_message');
}
}
and lastly in your view:
<div id="container">
<?php
echo '<pre>';
var_dump($x = $this->session->userdata('someIns'));
echo '</pre>';
echo '<pre>';
echo $x->testProp;
echo '</pre>';
echo '<pre>';
var_dump($this->session->all_userdata());
echo '</pre>';
?>
</div>
the output would be:
object(Test)#15 (1) {
["testProp"]=>
string(7) "testing"
}
testing
array(6) {
//some session data
["user_data"]=>
string(0) ""
["someIns"]=>
object(Test)#15 (1) {
["testProp"]=>
string(7) "testing"
}
}
if you noticed I used echo $x->testProp directly after fetching it from the session.
No serialization needed here.
With serialization:
Controller:
class Welcome extends CI_Controller {
public function index()
{
$this->load->library('test');
$this->session->set_userdata('someIns', serialize($this->test));
$this->load->view('welcome_message');
}
}
View:
<div id="container">
<?php
echo '<pre>';
var_dump($x = $this->session->userdata('someIns'));
echo '</pre>';
echo '<pre>';
$y = unserialize($x);
echo $y->testProp;
echo '</pre>';
echo '<pre>';
var_dump($this->session->all_userdata());
echo '</pre>';
?>
</div>
Results:
string(44) "O:4:"Test":1:{s:8:"testProp";s:7:"testing";}"
testing
array(6) {
//some session data
["user_data"]=>
string(0) ""
["someIns"]=>
string(44) "O:4:"Test":1:{s:8:"testProp";s:7:"testing";}"
}
the word testing is still being echoed out.
Now your problem, apparently, is that you are getting your FB class in a wrong way,
it is a library. Thus, you need to load your library first, as I did in the above example,
$this->load->library('test');
$this->session->set_userdata('someIns', $this->test);
or after serializing it. $this->test here is an instance of the Test class in the library folder.
So I have a problem I have an array that is passes to setData function
after that I call getE that suppose to return the array but instead I'm getting Null what am I doing wrong?
<?php
class Se {
public $data1;
public function setData(array $data){
if (empty($data)) {
throw new InvalidArgumentException('The name of an employee cannot be empty.');
}
$data1 = $data;
$data1 = array_values($data1);
var_dump($data1);
}
public function getE(){
return $data1[0];
}
}
$tmpaaa= array('3333','222');
$ttt = new Se();
$ttt->setData($tmpaaa);
echo $ttt->getE();
So my revised code looks like this now
class Se {
public $data1;
public function setData(array $data)
{
if (empty($data))
{
throw new InvalidArgumentException('The name of an employee cannot be empty.');
}
$this->data1 = $data;
}
public function getE()
{
return $this->$data1[0];
}
};
$tmpaaa= array('3','2');
$ttt = new Se();
$ttt->setData($tmpaaa);
echo $ttt->getE();
?>
In order to access class instance properties from within the class, you need to prefix the variable name with $this. See http://php.net/manual/language.oop5.properties.php
To fix your problem, change this in setData
$data1 = $data;
$data1 = array_values($data1);
var_dump($data1);
to this
$this->data1 = array_values($data);
var_dump($this->data1);
and getE to
public function getE(){
return $this->data1[0];
}
Update
As it appears the $data1 property is required in Se, I'd set it in the constructor, eg
public function __construct(array $data) {
$this->setData($data);
}
and instantiate it with
$ttt = new Se($tmpaaa);
echo $ttt->getE();
It is also recommended not closing the php tag in a class file, this prevents space issues.
<?php
class Se {
public $data1;
public function setData(array $data)
{
if (empty($data))
{
throw new InvalidArgumentException('The name of an employee cannot be empty.');
}
$this->data1 = array_values($data); //you error was here, no need to to assign $data twice so I deleted top line.
}
public function getE()
{
return $this->data1[0];
}
}
$tmpaaa = array('3333','222');
$ttt = new Se();
$ttt->setData($tmpaaa);
echo $ttt->getE();
I'm trying to learn how to print results from a query, but I'm getting confused.
Config Table:
site_id | site_name | site_description
1 Test Testing
Config:
private $hostname = 'localhost';
private $username = 'blah';
private $password = 'blah';
private $database = 'blah';
public function __construct()
{
$this->connection = new mysqli($this->hostname,$this->username,$this->password,$this->database);
if($this->connection->connect_errno)
{
die('Error: ' . $this->connection->error);
}
}
public function query($query)
{
return $this->connection->query($query);
}
public function __destruct()
{
$this->connection->close();
}
Code #1:
public function __construct()
{
$this->db = new Config;
$si = $this->db->query('SELECT * FROM config');
while($site_if = $si->fetch_array())
{
$this->site_info[] = $site_if;
}
}
public function getSiteName()
{
echo $this->site_info['site_name'];
}
This prints nothing.
Code #2:
public function __construct()
{
$this->db = new Config;
$si = $this->db->query('SELECT * FROM config');
while($site_if = $si->fetch_array())
{
$this->site_name_info = $site_if['site_name'];
}
}
public function getSiteName()
{
echo $this->site_name_info;
}
This prints the info, but is it the correct approach? Is there a way to print with Code #1?
All I want to do is echo site name. There is only one site name.
Without more info about your config table design the only think I can suggest is something like that:
while($site_if = $si->fetch_array())
{
$this->site_info[$site_if["NAME_COLUMN_NAME"]] = $site_if["VALUE_COLUMN_NAME"];
}
NAME_COLUMN_NAME and VALUE_COLUMN_NAME have to be replaced with column names from your table design.
After that you'll be able to get custom config parameter from $this->site_info array by it's name, eg.
public function getSiteName()
{
echo $this->site_info['site_name'];
}
In example #1, $this->site_info contains an array of arrays. To simply see the contents:
print_r($this->site_info);
To loop over the contents, printing the names of each row:
foreach ($this->site_info as $row){
echo $row['site_name'];
}