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();
Related
I use Laravel version 5.7 and want to get data from the database. I tried using $genre->name but it didn't work, and also I tried $genre->toArray() but got another error.
Controller
<?php
namespace App\Http\Controllers;
use App\genre;
class Mins extends Controller
{
public function genget($data)
{
foreach ($data as $key => $value) {
$genre = genre::where('name', $value)->first();
echo $genre->name;
}
}
}
Here's the data in $data when I var_dump.
array(4) { [0]=> string(6) "Comedy" [1]=> string(3)
"Action" [2]=> string(8) "Bad" [3]=> string(7) "Good" }
I'm getting the following error (echo in the controller):
"Trying to get property 'name' of non-object"
However, when I try to do dd($genre->name) in the controller I did get the data.
Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class genre extends Model
{
protected $fillable = ['name', 'slug'];
}
I'm also trying:
$genre = genre::where('name', $value)->first()->toArray();
dd($genre);
Response:
array:6 [▼
"id" => 1
"name" => "Comedy"
"slug" => "comedy"
"created_at" => "2019-01-11 15:02:31"
"updated_at" => "2019-01-11 15:02:31"
"deleted_at" => null
]
But when I call specified value like echo $g['name']; I get the error:
"Call to a member function toArray() on null"
I try to change the $value using a string like:
$genre = genre::where('name', 'Comedy')->first();
This works perfectly, does anyone know what the problem is?
Check for empty result :
foreach ($data as $key => $value)
{
$genre = genre::where('name', $value)->first();
if ($genre)
{
echo $genre->name;
}
}
Firstly, with the code in your example, I would suggest checking to see if the model actually exists before doing anything with it, this way you're not going to have an error thrown when it doesn't exist. When using first() it is either going to return the Eloquent model or null so an easy check would be something like:
$genre = genre::where('name', $value)->first();
if ($genre) {
echo $genre->name;
}
That being said, performing a query inside a loop is pretty inefficient and considered bad practice. In this case you'd be better of using whereIn() and then looping through the results:
public function genget($data)
{
$genres = genre::whereIn('name', $data)->get();
foreach ($genres as $genre) {
echo $genre->name;
}
}
This way you're only ever performing one query (instead of 4 like in your example) and you won't have to worry about them existing when you loop through them.
NB
This isn't essential but I would strongly recommend following the PSR's, specifically in this case PSR-1 - Namespace and Class Names so you're genre class should be Genre e.g.
class declaration: class Genre (not class genre)
class file name: Genre.php (not genre.php)
class usage: Genre::someMethod() (genre::someMethod())
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.
I have a return value and I var_dump() to get the data.
var_dump($values)
this is the result:
object(WP_Error)#171 (2) { ["errors":"WP_Error":private]=> array(1) { ["upload_error"]=> array(1) { [0]=> string(28) "0B1n5jy1RsUExUWNCN01GeXBvWmM" } } ["error_data":"WP_Error":private]=> array(0) { } }
I am new with PHP Object retrieving I tried foreach but noting happens.
what I am trying to do is to get this value:
["upload_error"]=> array(1) { [0]=> string(28) "0B1n5jy1RsUExUWNCN01GeXBvWmM" }
the 0B1n5jy1RsUExUWNCN01GeXBvWmM that set on upload_error
WP_Error is a php class, your values is a instance. see https://codex.wordpress.org/Class_Reference/WP_Error for detail
if you want to get error, you can't get it directly because it is private( although you can see it in var_dump), the doc above will tell you how to get it via provided public methods.
the following code snippet may give you a better understanding for using foreach on a class instance. you can look at manual for more detail. http://php.net/manual/en/language.oop5.iterations.php
class WP_Error_Example
{
private $errors = array();
public $pk = 1;
}
$e = new WP_Error_Example();
$e2 = new WP_Error_Example();
// #1,#2 in var_dump shows how many instance?
var_dump($e);
var_dump($e2);
// only public value
foreach ($e as $k => $v) {
var_dump($k, $v);
}
Note: you need to save this to a single file and run it using commandline. eg:php demo.php PS: var_dump it not pretty in commandline.
I'm trying to get a multi-dimensional array from an Entity.
Symfony Serializer can already convert to XML, JSON, YAML etc. but not to an array.
I need to convert because I want have a clean var_dump. I now have entity with few connections and is totally unreadable.
How can I achieve this?
You can actually convert doctrine entities into an array using the built in serializer. I actually just wrote a blog post about this today:
https://skylar.tech/detect-doctrine-entity-changes-without/
You basically call the normalize function and it will give you what you want:
$entityAsArray = $this->serializer->normalize($entity, null);
I recommend checking my post for more information about some of the quirks but this should do exactly what you want without any additional dependencies or dealing with private/protected fields.
Apparently, it is possible to cast objects to arrays like following:
<?php
class Foo
{
public $bar = 'barValue';
}
$foo = new Foo();
$arrayFoo = (array) $foo;
var_dump($arrayFoo);
This will produce something like:
array(1) {
["bar"]=> string(8) "barValue"
}
If you have got private and protected attributes see this link : https://ocramius.github.io/blog/fast-php-object-to-array-conversion/
Get entity in array format from repository query
In your EntityRepository you can select your entity and specify you want an array with getArrayResult() method.
For more informations see Doctrine query result formats documentation.
public function findByIdThenReturnArray($id){
$query = $this->getEntityManager()
->createQuery("SELECT e FROM YourOwnBundle:Entity e WHERE e.id = :id")
->setParameter('id', $id);
return $query->getArrayResult();
}
If all that doesn't fit you should go see the PHP documentation about ArrayAccess interface.
It retrieves the attributes this way : echo $entity['Attribute'];
PHP 8 allows us to cast object to array:
$var = (array)$someObj;
It is important for object to have only public properties otherwise you will get weird array keys:
<?php
class bag {
function __construct(
public ?bag $par0 = null,
public string $par1 = '',
protected string $par2 = '',
private string $par3 = '')
{
}
}
// Create myBag object
$myBag = new bag(new bag(), "Mobile", "Charger", "Cable");
echo "Before conversion : \n";
var_dump($myBag);
// Converting object to an array
$myBagArray = (array)$myBag;
echo "After conversion : \n";
var_dump($myBagArray);
?>
The output is following:
Before conversion :
object(bag)#1 (4) {
["par0"]=> object(bag)#2 (4) {
["par0"]=> NULL
["par1"]=> string(0) ""
["par2":protected]=> string(0) ""
["par3":"bag":private]=> string(0) ""
}
["par1"]=> string(6) "Mobile"
["par2":protected]=> string(7) "Charger"
["par3":"bag":private]=> string(5) "Cable"
}
After conversion :
array(4) {
["par0"]=> object(bag)#2 (4) {
["par0"]=> NULL
["par1"]=> string(0) ""
["par2":protected]=> string(0) ""
["par3":"bag":private]=> string(0) ""
}
["par1"]=> string(6) "Mobile"
["�*�par2"]=> string(7) "Charger"
["�bag�par3"]=> string(5) "Cable"
}
This method has a benefit comparing to Serialiser normalizing -- this way you can convert Object to array of objects, not array of arrays.
I had the same issue and tried the 2 other answers. Both did not work very smoothly.
The $object = (array) $object; added alot of extra text in my key
names.
The serializer didn't use my active property because it did not have is in front of it and is a boolean. It also changed the sequence of my data and the data itself.
So I created a new function in my entity:
/**
* Converts and returns current user object to an array.
*
* #param $ignores | requires to be an array with string values matching the user object its private property names.
*/
public function convertToArray(array $ignores = [])
{
$user = [
'id' => $this->id,
'username' => $this->username,
'roles' => $this->roles,
'password' => $this->password,
'email' => $this->email,
'amount_of_contracts' => $this->amount_of_contracts,
'contract_start_date' => $this->contract_start_date,
'contract_end_date' => $this->contract_end_date,
'contract_hours' => $this->contract_hours,
'holiday_hours' => $this->holiday_hours,
'created_at' => $this->created_at,
'created_by' => $this->created_by,
'active' => $this->active,
];
// Remove key/value if its in the ignores list.
for ($i = 0; $i < count($ignores); $i++) {
if (array_key_exists($ignores[$i], $user)) {
unset($user[$ignores[$i]]);
}
}
return $user;
}
I basicly added all my properties to the new $user array and made an extra $ignores variable that makes sure properties can be ignored (in case you don't want all of them).
You can use this in your controller as following:
$user = new User();
// Set user data...
// ID and password are being ignored.
$user = $user->convertToArray(["id", "password"]);
I'm trying to print data from an array. The array is from a class. I'm getting
array(0) { }
instead of:
Array ( [0] => header_index.php [1] => footer.php )
The code is:
<?php
class TemplateModel {
public function getTemplate($template = "index"){
switch($template){
case "index":
$templateconfig = array("header_index.php","footer.php");
break;
}
return $templateconfig;
}
}
$temodel = new TemplateModel();
var_dump(get_object_vars($temodel));
$temodel -> getTemplate();
?>
What i'm doing wrong? Thanks in Advance
var_dump(get_object_vars($temodel));
will output class member $temodel. There are no class member variables, so output is empty. If you want to output your array, you have to for example do this:
print_r($temodel -> getTemplate());
My immediate thoughts are it looks like you are setting the variables in the function 'getTemplate' and that is not being called until after the var_dump.
ADD:
And I just noticed you are not capturing the return of the function. You are var_dumping the object created from the class.
FIX:
<?php
class TemplateModel {
public function getTemplate($template = "index"){
switch($template){
case "index":
$templateconfig = array("header_index.php","footer.php");
break;
}
return $templateconfig;
}
}
$temodel = new TemplateModel();
$returned_var = $temodel -> getTemplate();
var_dump($returned_var);
?>
If you want to set the array as a variable of the object, that is a different problem.
It looks like you're not initializing the $templateconfig variable until getTemplate() is called. And you don't call it until after var_dump().
So basically, you're dumping an object that has no initalized member properties which is why you see an empty array.
Your object itself has no variables (properties) to be returned with a call to get_object_vars(). The $templateconfig variable only exists within the scope of the getTemplate() function and is not a property of the object.
If your intent is to make it a property of the object, you should do something like this:
class TemplateModel {
private $template_config = array(
'index' => array("header_index.php","footer.php"),
// add other configs here
);
public function getTemplate($template = "index"){
if(empty($template)) {
throw new Exception('No value specified for $template');
} else if (!isset($this->template_config[$template])) {
throw new Exception('Invalid value specified for $template');
}
return $this->template_config[$template];
}
}
$temodel = new TemplateModel();
var_dump($temodel->getTemplate());
Note here if you call get_object_vars() you still would get an empty array as I have made the $template_config variable private, forcing the caller to use the getTemplate() method to access the template data.