Is it possible to access object's properties, when you don't know just how their names will be written?
My problem is that when a query returns Zend_Db_Table_Rowset_Abstract object, there are some fields with names like "name_fr", "name_en", "name_au". I want to access either of them according to the current language used in the application. To achieve this I write the code this way:
$result = $myModel->fetchAll($query)->current();
$row = $result->toArray();
echo 'Your name is '.$row['name_'.$language];
This is very annoying. Is it possible to write a code like this for example:
$result = $myModel->fetchAll($query)->current();
echo 'Your name is '.$result->name_{$language};
This should work:
$result = $myModel->fetchAll($query)->current();
echo 'Your name is '.$result->{'name_'.$language};
When you use Zend_Db_Table and fetchAll()->current(), type of returned object is Zend_Db_Table_Row, which inherits from Zend_Db_Table_Row_Abstract. Zend_Db_Table_Row_Abstract implements ArrayAccess(manual) interface, which means you can refer to object properties using array key notation.
So, syntax:
'Your name is '.$row['name_'.$language];
should work without using toArray();
Try this:
$result->{"name_$language"}
Related
I am wondering that whether it is possible to write two different mysql queries in one php class object method and use those results in an another class method. Here's I am trying to do (I put only the relevant part of my code here), but I think it's not working:
<?php
public function sql()
{
$sql = "SELECT * FROM customers";
// Another sql
$sql_sales = "SELECT SUM(sales) as sales FROM customers";
// Execute this sql and result is stored in a variable
$this->sales = $row['sales'];
return $sql;
}
public function customers_list()
{
$sql = $this->sql();
$customers = '
<div id="customers">
<div id="customers_num"><span>'.$this->sales.'</span> Sales</div>
</div>';
return $customers;
}
?>
Can we use value of variable $this->sales inside another method?
If not then what's the correct way of getting it's value?
In case your code is inside a class and you're using an instantiated object :
From PHP basics
The pseudo-variable $this is available when a method is called from
within an object context. $this is a reference to the calling object
Therefore you can access any of your object properties inside its methods.
In your specific case $this->sales = $row['sales']; stores a value in its sales
property which can be used anywhere else in the object scope.
We can not get variable value like your approach. Your main query $sql is returning the result but the value of your second query $sql_sales is nowhere returned. That's why it is undefined property in your method customers_list().
The solution is to create a separate method to get $this->sales value. Then you can call this method in your customers_list() and access its value.
I have array which contains laravel model (App\User) attribute names like following:
$documents = array(
'passport_expire' => 22,
'residency' => 13
);
If I called these functions directly it will return a boolean value like:
App\User::find(2)->passport_expire;//will output true / false
I want to execute the functions inside a foreach:
foreach($documents as $type => $val){
// I want to call the attributes
App\User::find(1)->{$type};
//I want to call and execute App\User::find(1)->passport_expire and App\User::find(1)->residency
I read in php documentation about a way with similar approach called Variable functions but I don't know how to accomplish that in laravel.
How about
App\User::find(1)->$type;
Also you want to use string & variable
App\User::find(1)->$type . '_test';
However, if you want to use string as first, I think you need to create a variable beforehand and use first approach.
$type = "xx_$type_xx"
App\User::find(1)->$type;
Whereas, App\User::find(1)->{$type}; works,
But App\User::find(1)->{$type . 'text'}; doesn't work.
You're calling the attributes/properties as functions?
So far I think you meant variable variables.
If you want to access the properties like passport_expire or residency then you can try like
$user = App\User::find(1);
foreach (array_keys($documents) as $document) {
$documents[$document] = $user->{$document};
}
The above code will update the $documents array with the values of $user object's properties.
But, if you want to execute as functions as you mentioned, you need to try call_user_func or call_user_func_array
I have the following class with several properties and a method in PHP (This is simplified code).
class Member{
public $Name;
public $Family;
public function Fetch_Name(){
for($i=0;$i<10;$i++){
$this[$i]->$Name = I find the name using RegExp and return the value to be stored here;
$this[$i]->Family = I find the family using RegExp and return the value to be stored here;
}
}//function
}//class
In the function Fetch_Name(), I want to find all the names and families that is in a text file using RegExp and store them as properties of object in the form of an array. But I don't know how should I define an array of the Member. Is it logical or I should define StdClass or 2-dimension array instead of class?
I found slightly similar discussion here, but a 2 dimensional array is used instead of storing data in the object using class properties.
I think my problem is in defining the following lines of code.
$Member = new Member();
$Member->Fetch_name();
The member that I have defined is not an array. If I do define it array, still it does not work. I did this
$Member[]= new Member();
But it gives error
Fatal error: Call to a member function Fetch_name() on a non-object in
if I give $Member[0]= new Member() then I don't know how to make $Member1 or Member[2] or so forth in the Fetch_Name function. I hope my question is not complex and illogical.
Many thanks in advance
A Member object represents one member. You're trying to overload it to represent or handle many members, which doesn't really make sense. In the end you'll want to end up with an array that holds many Member instances, not the other way around:
$members = array();
for (...) {
$members[] = new Member($name, $family);
}
Most likely you don't really need your Member class to do anything really; the extraction logic should reside outside of the Member class, perhaps in an Extractor class or something similar. From the outside, your code should likely look like this:
$parser = new TextFileParser('my_file.txt');
$members = $parser->extractMembers();
I think you should have two classes :
The first one, Fetcher (or call it as you like), with your function.
The second one, Member, with the properties Name and Family.
It is not the job of a Member to fetch in your text, that's why I would make another class.
In your function, do your job, and in the loop, do this :
for($i = 0; $i < 10; ++$i){
$member = new Member();
$member->setName($name);
$member->setFamily($family);
// The following is an example, do what you want with the generated Member
$this->members[$i] = $member;
}
The problem here is that you are not using the object of type Member as array correctly. The correct format of your code would be:
class Member{
public $Name;
public $Family;
public function Fetch_Name(){
for($i=0;$i<10;$i++){
$this->Name[$i] = 'I find the name using RegExp and return the value to be stored here';
$this->Family[$i] = 'I find the family using RegExp and return the value to be stored here';
}
}
}
First, $this->Name not $this->$Name because Name is already declared as a member variable and $this->Name[$i] is the correct syntax because $this reference to the current object, it cannot be converted to array, as itself. The array must be contained in the member variable.
L.E: I might add that You are not writing your code according to PHP naming standards. This does not affect your functionality, but it is good practice to write your code in the standard way. After all, there is a purpose of having a standard.
Here you have a guide on how to do that.
And I would write your code like this:
class Member{
public $name;
public $family;
public function fetchName(){
for($i=0;$i<10;$i++){
$this->name[$i] = 'I find the name using RegExp and return the value to be stored here';
$this->family[$i] = 'I find the family using RegExp and return the value to be stored here';
}
}
}
L.E2: Seeing what you comented above, I will modify my answer like this:
So you are saying that you have an object of which values must be stored into an array, after the call. Well, after is the key word here:
Initialize your object var:
$member = new Memeber();
$memebr->fechNames();
Initialize and array in foreach
$Member = new Member();
foreach ($Member->Name as $member_name){
$array['names'][] = $member_name;
}
foreach ($Member->Family as $member_family) {
$array['family'][] = $member_family;
}
var_dump($array);
Is this more of what you wanted?
Hope it helps!
Keep on coding!
Ares.
I have a custom class object in PHP named product:
final class product
{
public $id;
public $Name;
public $ProductType;
public $Category;
public $Description;
public $ProductCode;
}
When passing an object of this class to my Data Access Layer I need to cast the object passed into a type of the product class so I can speak to the properties within that function. Since type casting in PHP works only with basic types what is the best solution to cast that passed object?
final class productDAL
{
public function GetItem($id)
{
$mySqlConnection = mysql_connect('localhost', 'username', 'password');
if (!$mySqlConnection) { trigger_error('Cannot connect to MySql Server!'); return; }
mysql_select_db('databaseName');
$rs = mysql_query("SELECT * FROM tblproduct WHERE ID='$id';");
$returnObject = mysql_fetch_object($rs, 'product');
return $returnObject;
}
public function SaveItem($objectToSave, $newProduct = false)
{
$productObject = new product();
$productObject = $objectToSave;
echo($objectToSave->Name);
$objectToSave->ID;
}
}
Right now I am creating a new object cast as a type of product and then setting it equal to the object passed to the function. Is there a better way of accomplishing this task? Am I going about the wrong way?
EDITED FOR CLARITY - ADD FULL PRODCUTDAL CLASS
You don't need to cast the object, you can just use it as if it was a product.
$name = $objectToSave->Name;
I´m not sure what you are trying to achieve, but if $objectToSave is already of class product:
You can simply call $objectToSave->SaveItem() (assuming SaveItem() is part of the product class) and access it´s properties in the function like $this->Name, etc.;
In your code $productObject and $objectToSave will hold a reference to the same object.
Type casts in PHP are done like this:
$converted = (type) $from;
Note, that this won't work if the object types are not compatible (if for example $form happens to be a string or object of mismatching type).
But usual solution (called Active Record pattern, present for example in Zend Framework) is to have a base class for a database item called Row. Individual items (for example the class product from your sample) then inherit from this class.
Typical ZF scenario:
$table = new Product_Table();
$product = $table->find($productId); // load the product with $productId from DB
$product->someProperty = $newPropertyValue;
$product->Save(); // UPDATE the database
Which is IMO much better than your solution.
EDIT:
You can't cast between two unrelated objects, it is not possible.
If you want to use the DAL like this, skip the "product" object and go for simple associative array. You can enumerate over its members with foreach, unlike object's properties (you could use reflection, but that's overkill).
My recommendation: Go for the Active Record pattern (it is easy to implement with magic methods). It will save you a lot of trouble.
Currently, you are creating a new Product, then discarding it immediately (as its reference is replaced by $objectToSave.) You will need to copy its properties one by one, I regret.
foreach (get_object_vars($objectToSave) as $key => $value)
{
$product->$key = $value;
}
(If the properties of $objectToSave are private, you will need to a expose a method to_array() that calls get_object_vars($this).)
Right now, I have this code where $obj_arr maybe contain array and an object.
$obj_temp = array ($obj_identity, $arr_user, $obj_locale, $arr_query);
foreach ($obj_temp as $maybe_arr) {
if (is_array($maybe_arr)) :
$name = (string) key($maybe_arr);
if (is_object($maybe_arr)) :
???? // how to retrieve a class name ?
endif;
$obj_arr[$name] = $maybe_arr;
}
obj_will_be_extract($obj_arr);
function obj_will_be_extract($obj_arr) {
extract($obj_arr);
//Do the rest
}
I need to create an array consist of combination of objects and arrays. Cause I need to extract it, then how to get an object name?
Use get_class to get the class name of an object.
Since PHP 5.5 you can use MyAction::class statement, so you can get a class name without class initialization