It's possible to create another instance to send as parameters on the current instance in PDO::fetchAll()?
if \PDO::FETCH_PROPS_LATE is set it will FIRSTLY call the __construct and SECONDLY set the properties. so the values you have passed to the __construct via the array will be overwritten.
But, when it overwritte the values, it doesn't understand the Voucher instance.
It is better illustrate
e.g.
<?php
class Voucher {
private $CD_ID, $CD_VOUCHER, $NR_EXPIRATION, $DT_VOUCHER, $IE_STATUS;
public function __construct($CD_ID, $CD_VOUCHER, $NR_EXPIRATION, $DT_VOUCHER, $IE_STATUS) {
$this->CD_ID = $CD_ID;
$this->CD_VOUCHER = $CD_VOUCHER;
$this->NR_EXPIRATION = $NR_EXPIRATION;
$this->DT_VOUCHER = $DT_VOUCHER;
$this->IE_STATUS = $IE_STATUS;
}
}
class Authentication {
private $CD_AUTH, $DT_AUTH, Voucher $CD_VOUCHER, $CD_IP, $CD_MAC, $CD_LOG;
public function __construct($CD_AUTH, $DT_AUTH, Voucher $CD_VOUCHER, $CD_IP, $CD_MAC, $CD_LOG) {
$this->CD_AUTH = $CD_AUTH;
$this->DT_AUTH = $DT_AUTH;
$this->CD_VOUCHER = $CD_VOUCHER;
$this->CD_IP = $CD_IP;
$this->CD_MAC = $CD_MAC;
$this->CD_LOG = $CD_LOG;
}
}
public function getAuthentications() {
try {
$sth = $this->db->prepare("SELECT `TB_AUTENTICACAO`.`CD_AUTH`, `TB_AUTENTICACAO`.`DT_AUTH`, `TB_VOUCHER`.`CD_ID`, `TB_VOUCHER`.`CD_VOUCHER`, `TB_VOUCHER`.`NR_EXPIRATION`, `TB_VOUCHER`.`DT_VOUCHER`, `TB_VOUCHER`.`IE_STATUS`, `TB_AUTENTICACAO`.`CD_IP`, `TB_AUTENTICACAO`.`CD_MAC`, `TB_AUTENTICACAO`.`CD_LOG` FROM `TB_AUTENTICACAO` INNER JOIN `TB_VOUCHER` ON `TB_VOUCHER`.`CD_ID` = `TB_AUTENTICACAO`.`CD_VOUCHER`;");
$sth->execute();
return $sth->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, "Models\\Authentication", array("TB_AUTENTICACAO.CD_AUTH", "TB_AUTENTICACAO.DT_AUTH", new \Models\Voucher("TB_VOUCHER.CD_ID", "TB_VOUCHER.CD_VOUCHER", "TB_VOUCHER.NR_EXPIRATION", "TB_VOUCHER.DT_VOUCHER", "TB_VOUCHER.IE_STATUS"), "TB_AUTENTICACAO.CD_IP", "TB_AUTENTICACAO.CD_MAC", "TB_AUTENTICACAO.CD_LOG"));
} catch (Exception $exc) {
die($exc->getMessage());
}
}
The result must be:
e.g.
Models\Authentication Object (
[CD_AUTH:Models\Authentication:private] => 2
[DT_AUTH:Models\Authentication:private] => 2016-03-22 10:44:00
[CD_VOUCHER:Models\Authentication:private] => Models\Voucher Object (
[CD_ID:Models\Voucher:private] => 1
[CD_VOUCHER:Models\Voucher:private] => xYgPB5
[NR_EXPIRATION:Models\Voucher:private] => 720
[DT_VOUCHER:Models\Voucher:private] => 2016-03-18 17:00:00
[IE_STATUS:Models\Voucher:private] => 0
)
[CD_IP:Models\Authentication:private] => 10.10.10.10
[CD_MAC:Models\Authentication:private] => abc
[CD_LOG:Models\Authentication:private] => 1
)
but I get:
e.g.
Models\Authentication Object (
[CD_AUTH:Models\Authentication:private] => 2
[DT_AUTH:Models\Authentication:private] => 2016-03-22 10:44:00
[CD_VOUCHER:Models\Authentication:private] => xYgPB5
[CD_IP:Models\Authentication:private] => 10.10.10.10
[CD_MAC:Models\Authentication:private] => abc
[CD_LOG:Models\Authentication:private] => 1
[CD_ID] => 1
[NR_EXPIRATION] => 720
[DT_VOUCHER] => 2016-03-18 17:00:00
[IE_STATUS] => 0
)
I would just keep it simple and define the variable as a class in the class itself. However, I am not sure why you have this issue, perhaps its because you're not attaching a variable to the new class?
If you're using a PHP 5.6+ you can make use of variable-length argument lists.
Seeing your code, I think it will boost read-ability by a-lot but the downside is that you need to make sure the correct number of variables are parsed into the constructor.
class Authentication {
private $CD_AUTH, $DT_AUTH, $CD_VOUCHER, $CD_IP, $CD_MAC, $CD_LOG;
public function __construct($CD_AUTH, $DT_AUTH, array $CD_VOUCHER, $CD_IP, $CD_MAC, $CD_LOG) {
...
$this->CD_VOUCHER = new \Models\Voucher(...$CD_VOUCHER);
...
# or go anonymous in php 7
$this->CD_VOUCHER = new class(...$CD_VOUCHER){
function __construct($CD_ID, $CD_VOUCHER, $NR_EXPIRATION, $DT_VOUCHER, $IE_STATUS){
...
}
}
}
}
public function getAuthentications() {
try {
$sth = $this->db->prepare("...");
$sth->execute();
return $sth->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, "Models\\Authentication", array("TB_AUTENTICACAO.CD_AUTH", "TB_AUTENTICACAO.DT_AUTH", ["TB_VOUCHER.CD_ID", "TB_VOUCHER.CD_VOUCHER", "TB_VOUCHER.NR_EXPIRATION", "TB_VOUCHER.DT_VOUCHER", "TB_VOUCHER.IE_STATUS"], "TB_AUTENTICACAO.CD_IP", "TB_AUTENTICACAO.CD_MAC", "TB_AUTENTICACAO.CD_LOG"));
} catch (Exception $exc) {
die($exc->getMessage());
}
}
Related
How i can read this array alone $var['shipment_number'] don't work?
EinName\EINUNTERNEHMEN\Response Object
(
[shipment_number:EinName\EINUNTERNEHMEN\Response:private] => 222253010000075775
[piece_number:EinName\EINUNTERNEHMEN\Response:private] =>
[label:EinName\EINUNTERNEHMEN\Response:private] => https://cig.Einurl.com
[returnLabel:EinName\EINUNTERNEHMEN\Response:private] =>
[exportDoc:EinName\EINUNTERNEHMEN\Response:private] =>
[labelType:EinName\EINUNTERNEHMEN\Response:private] => URL
[sequenceNumber:EinName\EINUNTERNEHMEN\Response:private] => 1
[statusCode:EinName\EINUNTERNEHMEN\Response:private] => 0
[statusText:EinName\EINUNTERNEHMEN\Response:private] => ok
[statusMessage:EinName\EINUNTERNEHMEN\Response:private] => Der Webservice wurde ohne Fehler ausgeführt.
[version:EinName\EINUNTERNEHMEN\Version:private] => 2.2
[mayor:EinName\EINUNTERNEHMEN\Version:private] => 2
[minor:EinName\EINUNTERNEHMEN\Version:private] => 2
)
Code link:
https://pastebin.com/uDm6neRt
What you have there is an object, specifically an instance of EinName\EINUNTERNEHMEN\Response. Further, the properties are private, so you can only access them directly from inside the class.
See this example:
<?php
class Response {
private $var;
public function __construct($var) {
$this->var = $var;
}
public function getVar() {
return $this->var;
}
}
$res = new Response("test");
echo $res->getVar(); // test
echo $res->var; // fatal error, attempting to access a private property
Demo
So, if you don't have access to the class, to get the properties you need to use the getter, if it exists. Check the documentation of your Response class, by convention it should look like this:
echo $var->getShipmentNumber();
So, let's say I have this dummy code in one file:
<?php
class Dice
{
public $maxPossibleNo;
public $secretNumber;
function __construct($no_of_dice=1)
{
// how many possible dice number to enroll
$this->maxPossibleNo = $no_of_dice * 6;
// do shaking dice
$this->secretNumber = $this->getSecretNumber();
}
function getSecretNumber()
{
return rand(1, $this->maxPossibleNo);
}
function roll()
{
$found = false;
list($array1, $array2) = array_chunk(range(1, $this->maxPossibleNo), ceil($this->maxPossibleNo/2));
/*
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Array
(
[0] => 4
[1] => 5
[2] => 6
)
*/
$guess = new Guess();
echo $this->secretNumber;
echo $guess->checkSecretNumber();
}
}
class Guess extends Dice
{
function checkSecretNumber()
{
return $this->secretNumber;
}
function isGreaterThan($x)
{
return $x > $this->secretNumber;
}
function isLessThan($x)
{
return $x < $this->secretNumber;
}
function isEqual($x)
{
return $x == $this->secretNumber;
}
}
$game = new Dice('1');
$game->roll();
Result:
65
43
54
Expected Result:
66
33
55
I want the Guess class to be able to access the secret number of the Dice class without having to roll it again. So I can manipulate the Guess class with other function.
EDIT:
Expectation flow: The main class will only called once (to generate
the secret number), while i will need to do loop checking for the
secret number for many times. (I guess the way is to create another
class of it, and it will be able to be called repeatly for auto
checking purpose, but i had did mistake here and dont have any idea
how to correct this part.)
Any suggested correction will be appreciated.
Thank you
when you create a new Guess(), it runs the constructor of Dice automatically, since Guess extends dice. The secret number in the Guess instance is not the secret number of the first Dice instance, it's a separate instance. I think your design is flawed. Why does Guess need to extend Dice? A guess is not logically a different implementation of a Dice (which is what you'd (logically) normally use subclasses for).
Here's how I would do it (without knowing anything further about what exactly you want to achieve):
<?php
class Dice
{
public $maxPossibleNo;
public $secretNumber;
function __construct($no_of_dice=1)
{
// how many possible dice number to enroll
$this->maxPossibleNo = $no_of_dice * 6;
// do shaking dice
$this->secretNumber = $this->getSecretNumber();
}
function getSecretNumber()
{
return rand(1, $this->maxPossibleNo);
}
function roll()
{
$found = false;
list($array1, $array2) = array_chunk(range(1, $this->maxPossibleNo), ceil($this->maxPossibleNo/2));
/*
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Array
(
[0] => 4
[1] => 5
[2] => 6
)
*/
}
}
class Guess
{
private $dice;
function __construct(Dice $d)
{
$this->dice = $d;
}
function checkSecretNumber()
{
return $this->dice->secretNumber;
}
function isGreaterThan($x)
{
return $x > $this->dice->secretNumber;
}
function isLessThan($x)
{
return $x < $this->dice->secretNumber;
}
function isEqual($x)
{
return $x == $this->dice->secretNumber;
}
}
$dice = new Dice('1');
$dice->roll();
$guess = new Guess($dice);
echo $dice->secretNumber;
echo $guess->checkSecretNumber();
I have a class UserFavorite that extends User.
When i create new object with the class constructor setters cannot set properties.
Constructor:
public function __construct($username, $tabId, $favName, $favUrl = null, $favPosition = null, $favComment = null) {
parent::__construct($username);
$this->tabId = $this->setTabId($tabId);
$this->favName = $this->setFavName($favName);
$this->favUrl = $this->setFavUrl($favUrl);
$this->favPosition = $this->setFavPosition($favPosition);
if ($favComment) {
$this->favComment = $this->setFavComment($favComment);
}
}
Setter:
public function setFavUrl($favUrl) {
$url = filter_var($favUrl, FILTER_VALIDATE_URL);
if (!$url) {
echo $this->showError(...);
exit;
}
echo $url; // THIS LOGS THE URL
$this->favUrl = $url;
}
I creatirng new instance $fav = new UserFavorite($user->getUsername(), 1, 'favorite', 'http://abv.bg', 5, 'mamatisiebalo' );
And when i print $fav i receive :
favorite<pre>UserFavorite Object
(
[favName:UserFavorite:private] =>
[tabId:UserFavorite:private] =>
[favUrl:UserFavorite:private] =>
[favPosition:UserFavorite:private] =>
[favComment:UserFavorite:private] =>
[_favId:UserFavorite:private] =>
[username:protected] => myUserName
[_userId:protected] => 1
)
Any ideas?
You are setting $this->favUrl in the setter function, then overwritting it by assigning the result of the setter function to the same variable.
If you change
$this->favUrl = $this->setFavUrl($favUrl);
To
$this->setFavUrl($favUrl);
You should be OK.
Using the following:
$last_book = tz_books::getLast($request->db, "WHERE book_id='{$request->book_id}'");
I get the following php object array,
[0] => tz_books Object
(
[db:tz_books:private] => com Object
[id] => 64BEC207-CA35-4BD2
[author_id] => 4F4755B4-0CE8-4251
[book_id] => 8FC22AA0-4A60-4BFC
[date_due] => variant Object
)
I then want to use the author_id, but for some reason it's not working.
Trying to use:
$tz_books->author_id;
Using print_r($last_book); prints the array to the console just fine. And Doing the following just to see if the correct variable was being used:
$author = $tz_books->author_id;
print_r($author);
Nothing is printed to the console, and even after digging through the php manual and trying a lot of alternatives, I can't seem to grab that variable. I'm hoping i'm making a rookie mistake and overlooking something stupid. Thank you for any help!
Edit: Class definition
private $db;
public $id;
public $author_id;
public $book_id;
public $date_due;
public function __construct($db, $values=null) {
$this->db = $db;
if ( $values != null ) {
foreach ( $values as $var => $value ) {
$this->$var = $value;
}
}
}
public static function retrieveAll($db, $where='', $order_by='') {
$result_list = array();
$query = 'SELECT '.
'id, '.
'author_id, '.
'book_id, '.
'date_due '.
"FROM tz_books $where $order_by";
$rs = $db->Execute($query);
while ( !$rs->EOF ) {
$result_list[] = new tz_books($db, array(
'id' => clean_id($rs->Fields['id']->Value),
'author_id' => clean_id($rs->Fields['author_id']->Value),
'book_id' => clean_id($rs->Fields['book_id']->Value),
'date_due' => $rs->Fields['date_due']->Value,
));
$rs->MoveNext();
}
$rs->Close();
return $result_list;
}
Your result object seems to be an array of books with 1 element.
Try
echo $tz_books[0]->author_id;
BTW, it also looks like you're escaping input by putting single quotes. This is not a reliable/recommended method. Use a database-specific escape function like this
I am writing this comment class:
class Comment {
public $id;
public $post_id;
public $name;
public $email;
public $website;
public $body;
public $date;
public $ip_address;
public $status;
function __construct($id) {
global $db;
$resc = $db->query("SELECT * FROM blog_comments WHERE id='$id' LIMIT 1");
while($row = $db->fetch_assoc($resc)) {
while ($comment = current($row)) {
$key = key($row);
$this->$key = $comment{$key};
next($row);
}
}
}
}
Here is what the query inside the constructor will return when run in the database:
query results http://17webshop.com/wp-content/uploads/2009/10/Picture-2.png
But when I run it, this is what print_r(new Comment(1)); spits out:
Comment Object
(
[id] => 1
[post_id] => 1
[name] => J
[email] => j
[website] => h
[body] => b
[date] => 1
[ip_address] => :
[status] => 1
)
Any ideas why I'm only getting the first character of each field?
Thanks.
You want
$comment[$key]
$comment{$key} will give you the nth character of a string. Since $key itself is a string, PHP converts that to an integer 0 and you get the first char.
current/next is painful, and I'm not sure what's with the {} dereferencing.
Why not just:
$resc = $db->query("SELECT * FROM blog_comments WHERE id='$id' LIMIT 1");
while($row = $db->fetch_assoc($resc)) {
foreach($row as $key=>$value){
$this->$key = $value;
}
}
I think you need to change this line:
$this->$key = $comment{$key};
with:
$this->$key = $comment[$key];