I have one object being the result of a database query, looking something like this (var_dump output):
object(stdClass)#17 (6) {
["id"]=>
string(1) "1"
["title"]=>
string(20) "Some Title"
["description"]=>
string(41) "Some really good stuff. Description here."
["slug"]=>
string(19) "some-slug-url"
["picture_url"]=>
NULL
["price"]=>
string(4) "5.99"
}
I just need all property values "transferred" to a different class which has the same property names. Is there a simple way to do this?
Take a look at PHP's get_object_vars()-function to achieve the desired effect without tons of assignment statements:
foreach (get_object_vars($sourceObject) as $name => $value) {
$destinationObject->$name = $value;
}
You should make sure that you add sufficient error-checking to this, depending on your needs.
The simple and "failsafe" solution
$target = new MyClass;
$target->id = $source->id;
$target->title = $source->title;
// and so on
Its a little bit more to code, but the benefits are
If some property of $source change, you will notice it (because its missing in $target)
You can name the properties of $target completely independent from $source
You see, what happens
Related
I have some codes like blow,
class Tool{
function getData(){
$res = array('name'=>'jay','age'=>22,'job'=>'developer','ID'=>1233211234567);
$res = (object)$res;
var_dump(111,$res);
$resLog = $res;
$this->resFilter($resLog);
var_dump(222,$res);
//...log code
}
function resFilter($res){
unset($res->ID);
}
}
echo '<pre>';
$t = new Tool;
$t->getData();
die;
and I doubt why after call function resFilter in function getData the var_dump(222,$res); will be this :
int(111)
object(stdClass)#2 (4) {
["name"]=>
string(3) "jay"
["age"]=>
int(22)
["job"]=>
string(9) "developer"
["ID"]=>
int(1233211234567)
}
int(222)
object(stdClass)#2 (3) {
["name"]=>
string(3) "jay"
["age"]=>
int(22)
["job"]=>
string(9) "developer"
}
so you can see in second part of var_dump have no ID field? Who can help me , and tell me why?
update:
thanks for your answer, and I try this $resLog = clone($res); will work fine.
Best explanation is here, also with an example like yours :
http://php.net/manual/en/language.oop5.references.php
Long story short : When you apply the resFilter method you send the $resLog object as input and that object has the same identifier like $res because you made the $resLog = $res; It is rather the same thing if you had a normal variable but sent it with reference in a method.
When an object is sent by argument, returned or assigned to another
variable, the different variables are not aliases: they hold a copy of
the identifier, which points to the same object.
PHP implements shallow copies unless instructed otherwise. So when you copy the object you do not actually clone it completely, you work with a reference instead. Therefore the $this->resFilter($resLog); call will delete the ID propety in the referenced object too.
I have an array with the following contents:
$tester
array(1) {
[0]=>
object(CategoryItem)#79 (17) {
["type"]=>
string(0) ""
["addedInVersion"]=>
string(4) "0.02"
["lastUpdatedInVersion"]=>
string(4) "0.02"
["AToZ"]=>
bool(false)
["name"]=>
string(22) "Page Name"
["scopeNotes"]=>
string(0) ""
["historyNotes"]=>
string(13) "Added in 0.02"
["broaderItems"]=>
array(0) {
}
I want to echo out the name, if this case Page Name and then use this in an if statement.
I have but this errors, I also tried $tester->CategoryItem->name but no joy.
Is there anything obvious I am missing?
You need to access it like this:
$name = $tester[0]->name;
echo $name;
you have some leaks in your php OOP understanding, you should fix them by following some tutorials like these ones:
http://www.killerphp.com/tutorials/object-oriented-php/
http://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762
http://www.tutorialspoint.com/php/php_object_oriented.htm
Now to answer your question, your code should be this:
$the_name = $tester[0]->name;
if($the_name == 'whatever value you want') {
echo $the_name;
}
first of all, your initial variable is a array, therefor, $tester[0], then, this position is an object of the class CategoryItem so you use scope: $tester[0]->value
As for the last of your values in the class properties, broaderItems, this is again an array, so to access one of his values, you will have to call it like:
$tester[0]->broaderItems[0]; //or whatever the keys you will have here
Hope this helps!
:D
How can I convert the below array to look like the one right below. I am trying to use array_map but i am confused on how to write the function.
array(3) {
["award_year"]=>
array(2) {
[0]=>
string(7) "1999-01"
[1]=>
string(7) "2010-02"
}
["award_title_user"]=>
array(2) {
[0]=>
string(1) "2"
[1]=>
string(2) "tt"
}
["award_description_user"]=>
array(2) {
[0]=>
string(1) "2"
[1]=>
string(3) "ddd"
}
}
This what i am trying to achieve:
array(2) {
[0]=>
array(3) {
["award_year"]=>
string(7) "2010-02"
["award_title_user"]=>
string(2) "tt"
["award_description_user"]=>
string(3) "ddd"
}
[1]=>
array(3) {
["award_year"]=>
string(7) "1999-01"
["award_title_user"]=>
string(1) "2"
["award_description_user"]=>
string(1) "2"
}
}
$newArr = [];
foreach($oldArr as $key=>$row) {
foreach($row as $index=>$item) {
$newArr[$index][$key] = $item;
}
}
this will solve it, but no checks if data is valid as you mentioned
First things first, #tzook-bar-noy's answer is a better answer in this case, and I am not even advocating the approach I am going to detail here.
When dealing with arrays, I always try to avoid generic loops (ie: foreach()) if I can, instead using the more functional-programming approach that you mention in your question: using functions like array_map(). However the functional-programming functions are very focused in what they do (which is their benefit: they make your code Cleaner), so to use them: you kinda gotta be wanting to do the specific operation they offer.
array_map() has a drawback for your purposes here, in that the mapped array has the same keys in the same order as the original array, which is not what you want here. You need to both turn your original array "inside out", but the ordering of the resultant array you want is the reverse of the original data. Not a good fit for array_map().
It's doable with array_map(), but it's like using a flathead screwdriver when you really need a Philips.
Here's an example:
<?php
$awards = [
"award_year" => ["1999-01", "2010-12"],
"award_title_user" => ["2", "tt"],
"award_description_user" => ["2", "ddd"]
];
$remappedAwards = array_map(function($year, $title, $description){
return [
"award_year" => $year,
"award_title_user" => $title,
"award_description_user" => $description
];
}, $awards["award_year"], $awards["award_title_user"], $awards["award_description_user"]);
$remappedAwards = array_reverse($remappedAwards);
echo "<pre>";
var_dump($remappedAwards);
echo "</pre>";
Obviously I've hardcoded the key names in here too which is less than ideal. One could contrive a generic approach, but by then we'd be so far beyond the actual intent of aaray_map() that the code complexity would be getting daft.
In other languages wherein these array-iteration functions are a bit better implemented (say JS or CFML) one might be able to come up with a half-decent answer with a .reduce() (JS, CFML) kind of operation. However PHP's array_reduce() (and its other array-iteration methods) are hamstrung by their poor implementation as they only pass the value to the callback. They really need to pass at least the index as well, and (less-often-useful, but handy sometimes ~) the array itself as additional arguments to make them anything more than a proof-of-concept. IMO, obviously (I'm biased, I do more JS & CFML than I do PHP, so my expectations are set higher).
Bottom line: array_map() was not a good fit for your requirement here, but I applaud your efforts for thinking to us it as the function-programming approach to array manipulation is definitely a better approach than generic looping where the requirement matches the functionality.
How would you a) fix a Smarty array in PHP and b) stick the result back into the Smarty array variable?
Have you ever worked on a problem, and you thought you were SO close to resolving it, but the target keeps on slipping farther and farther away? I spent half a day on this, looking up documentation, searching for examples...but I must be missing something very basic.
Premise: I have a Smarty array with duplicate entries (and for now I cannot change the way this gets created, because the Smarty code is encoded in a template). This causes problems, because now I get multiple entries for the same product in the shopping cart. RIGHT NOW, I honestly cannot change the logic of how this was put together.
Here's what I got:
Smarty:
{$products}
In my scenario, {$products} contains four entries like so:
array(1) { [0]=> array(12) { ["pid"]=> string(2) "13" ["domain"]=> NULL
["billingcycle"]=> string(4) "free" ["configoptions"]=> string(0) ""
["customfields"]=> array(0) { } ["addons"]=> array(0) { } ["server"]=> string(0) ""
["productinfo"]=> array(9) { ["pid"]=> string(2) "13" ["gid"]=> string(1) "2"
["type"]=> string(5) "other" ["groupname"]=> string(13) "Beta Products" ["name"]=>
string(44) "BetterStuff "Free Until 2014" Beta" ["description"]=> string(21)
"BetterStuff installer" ["freedomain"]=> string(0) "" ["freedomainpaymentterms"]=>
array(1) { [0]=> string(0) "" } ["freedomaintlds"]=> array(1) {[0]=> string(0) ""}}
["allowqty"]=> string(1) "0" ["qty"]=> int(1) ["pricing"]=> array(4) { ["baseprice"]=>
string(9) "$0.00 USD" ["setup"]=> string(9) "$0.00 USD" ["recurring"]=> array(0){}
["totaltoday"]=> string(9) "$0.00 USD" } ["pricingtext"]=> string(5) "FREE!" } }
In PHP, I can easily use array-unique, to get rid of the 3 exact copies within this array, and be left with just one (as the one I just showed above).
{php}
$var = $this->get_template_vars('products');
$var = array_unique($var);
$smarty = new Smarty();
$smarty->assign('newproducts', $var = array_unique($var));
var_dump($var);
{/php}
This works perfectly, in PHP, and the var_dump($var) contains one array item (just like the one I showed above). In PHP, when I check $var with is_array, the result is true.
Back in Smarty, however, {$newproducts} is NULL.
When I try to re-assign the original Smarty array {$products}, I get
an error message about not being allowed to add string values to the
array.
When I try to print out {$newproducts|#count}, I get 0. That's
slight;y confusing to me, because I believe that Smart arrays start
at 1, whereas PHP arrays are zero-based.
So although PHP considers the variable I assign to be the value for
the new variable an array, it doesn't come into Smarty as an array.
What am I doing wrong here? Do I need to explode or split my PHP array somehow, so that I can turn it into a Smarty variable?
And how can I "reset" the original {$products} array in Smarty to the new unique array value?
Anyone?
Since there is no real answer and I was stuck with the same problem, that is, not being able to call array_unique from the php side since I had no access to the code generating it.
Here is the code that worked for me in Smarty:
{foreach from=$items item=item}
{if !in_array($item, $array)}
<li>{$item}</li>
{append var='array' value=$item}
{/if}
{/foreach}
It makes use of the smarty append command, which will add items to an array. Furthermore I made use of in_array (scroll down to the bullet regarding php_functions) which is, among some other php functions available in Smarty.
I hope this might help someone else out!
{php}
// read data from CURRENT INSTANCE
$var = $this->get_template_vars('products');
$var = array_unique($var);
// create NEW INSTANCE
$smarty = new Smarty();
// assign to NEW INSTANCE
$smarty->assign('newproducts', $var = array_unique($var));
var_dump($var);
{/php}
so, you're creating a new smarty instance and assigning data to it. Is there a reason you believe said data would be available in the current instance?
try this:
{php}
// read data from CURRENT INSTANCE
$var = $this->get_template_vars('products');
$var = array_unique($var);
// assign to CURRENT INSTANCE
$this->assign('newproducts', $var = array_unique($var));
{/php}
And {php} is deprecated. You might want to look into Extending Smarty With Plugins
Man this JSON thing is chewing away at my day. Is it suppose to be this difficult? Probably not. Ok, so I am receiving a URL with a json data set in it.
It looks like this:
jsonval={%22Fname%22:+%22kjhjhkjhk%22,+%22Lname%22:+%22ghghfhg%22,+%22conf[]%22:+[%22ConfB%22,+%22ConfA2%22],+%22quote%22:+%22meat%22,+%22education%22:+%22person%22,+%22edu%22:+%22welding%22,+%22Fname2%22:+%22%22,+%22Lname2%22:+%22%22,+%22gender%22:+%22B2%22,+%22quote2%22:+%22Enter+your+meal+preference%22,+%22education2%22:+%22person2%22,+%22edu2%22:+%22weld2%22,+%22jsonval%22:+%22%22}
And when I run json_decode in PHP on it, it looks like this:
object(stdClass)#1 (13) { ["Fname"]=> string(9) "kjhjhkjhk" ["Lname"]=> string(7) "ghghfhg" ["conf[]"]=> array(2) { [0]=> string(5) "ConfB" [1]=> string(6) "ConfA2" } ["quote"]=> string(4) "meat" ["education"]=> string(6) "person" ["edu"]=> string(7) "welding" ["Fname2"]=> string(0) "" ["Lname2"]=> string(0) "" ["gender"]=> string(2) "B2" ["quote2"]=> string(26) "Enter your meal preference" ["education2"]=> string(7) "person2" ["edu2"]=> string(5) "weld2" ["jsonval"]=> string(0) "" }
I guess I should mention it was encoded as a serialized object from the form page and then encoded and sent over...Don't know if that will make a difference.
Anyway, I dutifully check the PHP manual, and everything, as always, looks simple enough to implement. And then, of course, I try it just the way they tell me and I miss something that's probably obvious to everyone here but me. This bit of code, returns nothing except my text that I'm echoing:
<?php
$json = $_GET['jsonval'];
$obj = var_dump(json_decode($json));
echo "<br><br>ELEMENT PLEASE!" . $obj;
print $obj->{"Fname"}; // 12345
?>
I mean, all I want is to see the values of my individual key/values and print them out. What have I done wrong here?
Thanks for any advice.
This line is completely wrong:
$obj = var_dump(json_decode($json));
var_dump() returns nothing
You need:
$obj = json_decode($json);
Turn display_errors on in your php.ini and set up ERROR_REPORTING = E_ALL. And continue developing with such settings.
You put this:
print $obj->{"Fname"}; // 12345
It should be
print $obj->Fname; // 12345
I think you are not calling out data from the object incorrectly.
Needs to be something like:
$data = (json_decode(urldecode('{%22Fname%22:+%22kjhjhkjhk%22,+%22Lname%22:+%22ghghfhg%22,+%22conf[]%22:+[%22ConfB%22,+%22ConfA2%22],+%22quote%22:+%22meat%22,+%22education%22:+%22person%22,+%22edu%22:+%22welding%22,+%22Fname2%22:+%22%22,+%22Lname2%22:+%22%22,+%22gender%22:+%22B2%22,+%22quote2%22:+%22Enter+your+meal+preference%22,+%22education2%22:+%22person2%22,+%22edu2%22:+%22weld2%22,+%22jsonval%22:+%22%22}')));
echo $data->Fname;