I really confused with the situation. I want to get data from function in my class, that created by ActiveRecord Model. Here a class:
class Bag extends ActiveRecord\Model {
static $table_name = "bags";
static $primary_key = 'bag_id';
public function get_pocket_types() {
$arr = json_decode($this->pocket_types);
return $arr;
}
}
I call it in my main code:
$bag = Bag::find_by_bag_id((int)$_GET['id']);
$types = $bag->get_pocket_types();
It seems to be good, but I have an error Notice: Undefined property: Bag::$pocket_types in models/Bag.php on line 21 when I try to get $this->pocket_types. This field is absolutely exists, like a field bag_id.
I've even tried to debug it (in function get_pocket_types() ):
echo $this->bag_id;
// OK
echo $this->bag_id_NOT_EXISTS;
// Fatal error: Uncaught exception 'ActiveRecord\UndefinedPropertyException' with message 'Undefined property: Bag->bag_id_NOT_EXISTS
// This is just for catch an error of REALLY not existed field
echo $this->pocket_types;
// Notice: Undefined property: Bag::$pocket_types in models/Bag.php on line 21
I called var_dump($this); in the function:
object(Bag)#16 (6) { ["errors"]=> NULL
["attributes":"ActiveRecord\Model":private]=> array(2) {
["bag_id"]=>
int(160)
["pocket_types"]=>
string(0) "" } ["__dirty":"ActiveRecord\Model":private]=> array(0) { } ["__readonly":"ActiveRecord\Model":private]=>
bool(false) ["__relationships":"ActiveRecord\Model":private]=>
array(0) { } ["__new_record":"ActiveRecord\Model":private]=>
bool(false) }
Somebody can explain what happens please?
Looks like you have created a custom getter with the same name as an attribute.
In which case you will need $this->read_attribute('pocket_types') instead of $this->pocket_types
Or, rename get_pocket_types to something like get_json_decoded_pocket_types.
Related
What i have learned about objects in php is that the hash with a number (#n) points to the instantiation times for example :
if we have something like this object(Index)#5 (1) means that we have 5 instances of the Index object.
However in my case i'm working on a custom PHP MVC i have only instantiated the class once (i'm sure only once. a model class directly within the controller ) but i'm getting an object like so
object(Timino\App\Models\Index)#5 (1)
so why is this happening ?
do namespaces affect this ! ?
does this have an affection to the performance ?!
Namespaces should not affect this. For performance issues, the number of objects during script runtime will only have an impact, if the script is getting close or over the max memory limit. FYI, here are some considerations about performance.
A simple example to show/explain the "object counter":
class TestClass {
public $number = 2;
}
class ClassInner {
protected $number = 5;
protected $innerObject;
public function __construct() {
$this->innerObject = new \stdClass();
}
}
$testInstance = new TestClass();
$classInner = new ClassInner();
$classInner2 = new ClassInner();
$testInstance2 = new TestClass();
$classInner3 = $classInner2;
echo '<pre>';
var_dump($testInstance);
var_dump($classInner);
var_dump($classInner2);
var_dump($testInstance2);
var_dump($classInner3);
echo '</pre>';
Should result in this output. Pleas have a look at the order of instances and count:
object(TestClass)#1 (1) {
["number"]=>
int(2)
}
object(ClassInner)#2 (2) {
["number":protected]=>
int(5)
["innerObject":protected]=>
object(stdClass)#3 (0) {
}
}
object(ClassInner)#4 (2) {
["number":protected]=>
int(5)
["innerObject":protected]=>
object(stdClass)#5 (0) {
}
}
object(TestClass)#6 (1) {
["number"]=>
int(2)
}
object(ClassInner)#4 (2) {
["number":protected]=>
int(5)
["innerObject":protected]=>
object(stdClass)#5 (0) {
}
}
I'm trying to implement a DataTable class in php which will be basically a table to contain data just like an sql table and will be made of array()
The class is defined as followed:
class DataTable{
protected static $tabela; // table
//columns and strips, each column point to a strip
public function __construct($colunas, $faixas) {
$this->tabela = array();
$this->constroiDt($colunas, $faixas); //builds the table
}
public function getRows($where){
// todo
}
public static function getTabela(){
return $this->tabela;
}
private function constroiDt($colunas, $faixas){
if(count($colunas)!= count($faixas)){
$this->tabela = null;
return;
}
$i=0;
foreach($colunas as $cl){
$this->tabela = array_merge($this->tabela, array($cl => $faixas[$i]));
$i += $i + 1;
}
// the result will be an array like ('col1' => ('val1','val2'), 'col2' => ('val1','val2'))
// if I want to access a value, just type array['col1'][0] for example
}
}
Outside of the class function, when I create an example DT and try to access it, it seems that will work:
$columns = array("name", "age");
$strips = array(array("someone","another person"),array("20","30"));
$dt1 = new DataTable($columns, $strips);
var_dump($dt1); // will print:
// object(DataTable)#1 (1) { ["tabela"]=> array(2) { ["nome"]=> array(2) { [0]=> string(6) "fulano" [1]=> string(7) "ciclano" } ["idade"]=> array(2) { [0]=> string(2) "20" [1]=> string(2) "30" } } }
But then I add echo "--- " . $dt1::getTabela()['nome'][0];
It doesn't even print the ---. var_dump($dt1::getTabela()) and var_dump($dt1->getTabela()) also is blank. What is being missed here? Tried also this but didn't work.
You shouldn't use $this in a static function / for static properties as there is not necessarily an object context to use.
Instead, you should use self::$tabela everywhere instead.
Or change your variable (and the related methods...) to a "normal" protected property:
protected $tabela;
You are mixing static variables with non static accesors
i just put your code and i got a lot of errors/notices
NOTICE Accessing static property DataTable::$tabela as non static on line number 10
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
NOTICE Accessing static property DataTable::$tabela as non static on line number 31
object(DataTable)#1 (1) { ["tabela"]=> array(2) { ["name"]=> array(2) { [0]=> string(7) "someone" [1]=> string(14) "another person" } ["age"]=> array(2) { [0]=> string(2) "20" [1]=> string(2) "30" } } }
FATAL ERROR Uncaught Error: Using $this when not in object context in /home/phptest/public_html/code.php70(5) : eval()'d code:20 Stack trace: #0 /home/phptest/public_html/code.php70(5) : eval()'d code(44): DataTable::getTabela() #1 /home/phptest/public_html/code.php70(5): eval() #2 {main} thrown on line number 20
I'm sending an object via my Action in Symfony, but I cannot retrieve it in my view.
This is the Action code:
public function testphpAction()
{
/*SOME DOCTRINE CODE*/
$productos = $consulta->getResult();
return $this->render('TPMainBundle:Default:test.html.php', array(
'productos' => $productos,
));
}
I tried the solutions from this thread but with no effort: PHP Error: Cannot use object of type stdClass as array (array and object issues)
This is the code of my view 'test.html.php':
foreach($productos as $producto) {
echo $producto['descripcion'];
}
// This displays the error: "Cannot use object of type TP\MainBundle\Entity\Works as array
So I tried the solution from the other thread:
foreach ($productos as $producto) {
$id = $producto->id;
echo $id;
//But it throws the error: Cannot access private property TP\MainBundle\Entity\Works::$id
Neither this worked:
$id = $productos->id;
// Throw: "Trying to get property of non-object"
How can I access it? I don't have this problem if I render to a twig template, but I need to use php.
The var_dump of $productos is this: (I ommited the other objects in this chain)
array(3) { [0]=> object(TP\MainBundle\Entity\Works)#290 (4) { ["id":"TP\MainBundle\Entity\Works":private]=> int(1) ["descripcion":"TP\MainBundle\Entity\Works":private]=> string(30) "Landing page for a toys store." ["img":"TP\MainBundle\Entity\Works":private]=> string(12) "images/1.jpg" ["preview":"TP\MainBundle\Entity\Works":private]=> string(13) "images/1m.jpg" }
Define your getters, and then use them.
for example in this
foreach ($productos as $producto)
{ $id = $producto->id; echo $id; }
Try
$producto->getId();
instead of
$producto->id;
assuming you defined your getter.
$id = $producto->id;
This won't work because whether the property is not publicly accessible or the Object does not have that property.
The Work object has description, but it's private, so you'd have to create a getter function to echo it.
e.g
echo $producto->getDescription();
Let's say I have a function which returns an object with one of it's parameters set to some certain value:
public function search($jobsdone, $date)
{
foreach ($jobsdone as $jd) {
if ($jd->date_worked == $date) return $jd;
}
}
Printing search($jobsdone, $key) yields such results:
object(JobDone)#378 (19) {
...
["attributes":protected]=>
array(9) {
["id"]=>
int(3593)
["user_id"]=>
int(13)
["object_id"]=>
int(99)
["job_id"]=>
int(130)
["date_worked"]=>
string(10) "2013-10-01"
["min_from"]=>
int(780)
["min_to"]=>
int(1080)
}
...
}
However, if I want to print out search($jobsdone, $key)->id, all I get is an error message of:
Trying to get property of non-object
What could I be missing here?
Your search function doesn't always return an object. Therefore, you get error Trying to get property of non-object whenever your search couldn't find a $jobdone object.
To clarify:
I'm building a Logger class that allows me to easily log messages:
lib.Logger.php:
<?php
class Logger {
private $handle;
public function __construct($log_name, $log_path) {
if ( ! is_dir($log_path))
throw new Exception('Log path does not exist.');
if ( ! in_array(strtolower(substr($log_name, 0, -4)), array('.log', '.txt')))
$log_name = "{$log_name}.log";
$this->handle = fopen("{$log_path}/{$log_name}", 'a');
$this->log('------------- Initializing ------------- '.get_parent_class($this));
}
// --------------------------------------------------------------------
public function __destruct() {
fclose($this->handle);
}
// --------------------------------------------------------------------
public function log($message) {
$time = date(DATE_RFC822);
$log = "[{$time}] {$message}\n";
fwrite($this->handle, $log);
}
}
?>
And I call this using:
MyController.php:
<?php
class MyController extends Controller {
$logger = new Logger('testlog','/path/to/logs/');
$logger->log('Logs are fun!');
}
?>
When I initialize the object:
$this->log('------------- Initializing ------------- '.get_parent_class($this));
I want to log the name of the object (or file) that is calling log() -- in this case, either MyController or /path/to/MyController.php.
I tried using get_parent_class(), but of course this doesn't work because Logger does not have a parent class per se.
Any ideas? thank you so much for the help!
Alex B
I suppose a solution could be to use debug_backtrace.
The given example gets a backtrace like this :
array(2) {
[0]=>
array(4) {
["file"] => string(10) "/tmp/a.php"
["line"] => int(10)
["function"] => string(6) "a_test"
["args"]=>
array(1) {
[0] => &string(6) "friend"
}
}
[1]=>
array(4) {
["file"] => string(10) "/tmp/b.php"
["line"] => int(2)
["args"] =>
array(1) {
[0] => string(10) "/tmp/a.php"
}
["function"] => string(12) "include_once"
}
}
So, should include what you want ;-)
Still, the solution that seems the best, in my opinion, would be to pass the information needed when calling the log method...
(Just feels more... natural ^^ But that's not a very rational opinion, I suppose ^^ )
You willl need to make use of the function debug_backtrace(). But note that the function is not very consistent in its return value (not every array key is always present, even if it should be - the index file can be missing, for example, indicating that the file is either unknown (eval'd code) or the same as the previous stack frame). The last function that was called before this one should be available at index 0:
$trace = debug_backtrace();
$calling_function = $trace[0]['function'];
The only way to handle this implicitly is to capture the output from debug_backtrace as the others have suggested.
If you are interested in an explicit approach, maybe this could be it
in Logger
public function initialize( $context )
{
$logMessage = '------------- Initializing ------------- ';
if ( is_object( $context ) )
{
$logMessage .= get_class( $context );
} else {
// do something else?
}
$this->log( $logMessage );
}
and then
class MyController extends Controller
{
public function someFunc()
{
$logger = new Logger('testlog','/path/to/logs/');
$logger->initialize( $this );
$logger->log('Logs are fun!');
}
}
I ran into (almost) this exact problem last night. I'm using debug_backtrace() (as many others have already mentioned) to solve it. I needed to know the module that contains the controller that was calling a certain function. Because my controllers contain the module name within the class name, I simply grabbed the return from debug_backtrace() and explode()ed it to fetch the module name.
Soulmerge makes a good point about the return not always being consistent, but if you structure your code a certain way you can definitely get an accurate enough return.