Parsing nested function body PHP - php

i am trying to get this working: It is ment to return any function or method where the different 'functional parts' are subgrouped. I have problems with the maybe nested {..{.{} } } function body. At the moment the search breaks of after the first following }.
I do have a little bit a hard time understanding lock arround and recursive handling of Regs. So if someone would like to give a brief overall view - would be great!
i understand enough for this..The Regex:
to work with preg_* in PHP with "/im" set
([\w ]+)?(function)+([\s]+[\w\d]+)([\s]*?\(([^\)]+)?\))([\s]?\{+[^\}]*\})
Here a sample of use (i dont have named subpatterns on this sample...):
<?php
$s=file_get_contents('sometestcode');
$p='/
([\w ]+)?(function)+([\s]+[\w\d]+)([\s]*?\(([^\)]+)?\))([\s]?\{+[^\}]*\})
/im';
$m=array();
preg_match_all($p,$s,$m,PREG_SET_ORDER);
var_dump($m);
?>
Here comes the output as expected:
// Here the subject:
public static private function __set($name,$val){
$this->DATA[$name] = $val;
foreach( /*do it*/ ){
//work it...
}
return $this;
}
// The return
array(6){
[1]=>
string(7) "public static private " //makes sence, ha?
[2]=>
string(8) "function"
[3]=>
string(6) " __set" // func/meth name
[4]=>
string(12) "($name,$val)"
[5]=>
string(10) "$name,$val" // (if passed)$argument...
[6]=>
string(60) "{
$this->DATA[$name] = $val;
foreach( /*do it*/ ){
//work it...
}
// Here is the my link
// How to style the regExpPress??
}"

Related

Avoid deep nesting when iterating through many combinations

Is there a more declarative / less horrible way of writing this (deliberately simplified) code?
I realise I can use ->each(), but that still doesn't get rid of the nesting in this case?
Note I do need to generate all the combinations, and I have a mixture of things to loop through - configuration data, ordinary arrays, Eloquent, though obviously I could convert them first...
foreach(config('app.goals') as $goal) {
foreach(config('app.age_groups') as $ages) {
foreach($regions as $region_name => $region_id) {
foreach($interests->pluck('name')->prepend('') as $interest) {
foreach(config('app.devices') as $device) {
$record = new Foo();
$record->goal = $goal;
$record->age = $age;
$record->region = $region_id;
$record->interest = $interest;
$record->device = $device;
$record->save();
}
}
}
}
}
Unclear if there's a Collection method that can help? e.g.
holygrail(config('app.goals'),config('app.age_groups'),$regions...)->each(function($combination) {
// logic for every combination
});
crossJoin() seems to do what I need, it creates an array matrix of every combination.
$matrix = collect($goals)->crossJoin(
$ages,
$regions,
$interests,
$devices
);
So you have an array full of elements, each of them a permutation, e.g:
array(5) {
[0]=>
string(5) "REACH"
[1]=>
string(5) "18-65"
[2]=>
string(9) "Worldwide"
[3]=>
string(11) "Programming"
[4]=>
string(7) "desktop"
}
The Laravel source is in: \Illuminate\Support\Arr::crossJoin

PHP is accessing nested arrays copying them?

Let's say I have an array (it really could have any depth):
$arr = array(
"lvl1" => array(
"lvl2 => ...
)
)
Now in a function I need to access it like this:
$path = array("lvl1", "lvl2", ...); // array of ordered indexes
$tmp = $arr;
foreach($path as $lvl){
...// other read-only/copy stuff happening on the array, no editing
$tmp = $tmp[$lvl];
}
At this point, just out of curiosity (no real optimization here), am I making copies of copies everytime? Or is it just using references automatically?
TL;DR If you are using PHP 7 the array won't be copied internally unless you change it. This is called copy-on-write.
To understand how PHP works under the hood you can read Reference Counting Basics:
A PHP variable is stored in a container called a "zval".
PHP is smart enough not to copy the actual variable container when it is not necessary.
Let's try to illustrate this on your simplified example using debug_zval_dump:
$array = [
'lvl1' => [
'lvl2' => [
'lvl3' => [
],
],
],
];
$path = ['lvl1', 'lvl2', 'lvl3'];
$tmp = $array;
foreach ($path as $lvl) {
debug_zval_dump($array);
$tmp = $tmp[$lvl];
}
debug_zval_dump($array);
If you run this code you will get the following output:
array(1) refcount(4){
["lvl1"]=>
array(1) refcount(1){
["lvl2"]=>
array(1) refcount(1){
["lvl3"]=>
array(0) refcount(1){
}
}
}
}
array(1) refcount(3){
["lvl1"]=>
array(1) refcount(2){
["lvl2"]=>
array(1) refcount(1){
["lvl3"]=>
array(0) refcount(1){
}
}
}
}
array(1) refcount(3){
["lvl1"]=>
array(1) refcount(1){
["lvl2"]=>
array(1) refcount(2){
["lvl3"]=>
array(0) refcount(1){
}
}
}
}
array(1) refcount(3){
["lvl1"]=>
array(1) refcount(1){
["lvl2"]=>
array(1) refcount(1){
["lvl3"]=>
array(0) refcount(2){
}
}
}
}
Pay attention to refcount: it changes, so internally PHP assigns by reference until you actually change the assigned value. You can read about this in the blog post by nikic:
The important difference to PHP 5 is that all variables were able to share the same array, even though some were PHP references and some weren’t. Only once some kind of modification is performed the array will be separated.

php array of objects can't get object property (Object of class stdClass could not be converted to string)

been searching for a solution all day long...
my variable name is $categoryFetchedAsObj
var_dump results :
array(104) {
[0]=>
object(stdClass)#411 (1) {
["categoryHive"]=>
string(4) "asfa"
}
[1]=>
object(stdClass)#412 (1) {
["categoryHive"]=>
string(13) "ENERGY DRINKS"
}
[2]=>
object(stdClass)#413 (1) {
["categoryHive"]=>
string(7) "KETCHUP"
}
[3]=>
object(stdClass)#414 (1) {
["categoryHive"]=>
string(6) "STICKS"
}
and so on
i call a function...
createSelectBlock("category",$categoryFetchedAsObj,"onchange=\"this.form.submit()\"",null,'categoryHive');
here is the instance of the function
createSelectBlock($name,$fetchedNamesAsArrayOfObj,$selectEvent,$objPropertyNameForOptionsValue,$objPropertyNameForOptionsName)
and here is where the error raises
foreach ($fetchedNamesAsArrayOfObj as $rowArrayObj) {
if(isset($objPropertyNameForOptionsValue) && isset($objPropertyNameForOptionsName)){
$selectBlock.="<option value=\"$rowArrayObj->$objPropertyNameForOptionsValue\">$rowArrayObj->$objPropertyNameForOptionsName</option>";
}
if(!isset($objPropertyNameForOptionsValue) && isset($objPropertyNameForOptionsName)){
$selectBlock.="<option value=\"$rowArrayObj->$objPropertyNameForOptionsName \">$rowArrayObj->$objPropertyNameForOptionsName</option>";
}
}
(Object of class stdClass could not be converted to string)
if i replace the
$rowArrayObj->$objPropertyNameForOptionsName
with
$rowArrayObj->categoryHive
everything works but the args of the function are not the same all the time .. obviously
i search this site found some suggestions.. but nothing worked
here is what i tryied
$objPropertyNameForOptionsName='$objPropertyNameForOptionsName';
$rowArrayObj->{'$objPropertyNameForOptionsName'};
any ideas?
after testing and over testing .. finlay i got it working...
this was the correct answer for my situation
if(isset($objPropertyNameForOptionsValue) && isset($objPropertyNameForOptionsName)){
$selectBlock.="<option value=".$rowArrayObj->$objPropertyNameForOptionsValue.">".$rowArrayObj->$objPropertyNameForOptionsName."</option>";
}
if(!isset($objPropertyNameForOptionsValue) && isset($objPropertyNameForOptionsName)){
$selectBlock.="<option value=".$rowArrayObj->$objPropertyNameForOptionsName.">".$rowArrayObj->$objPropertyNameForOptionsName."</option>";
}
hope it helped someone

Get all object from a "group" in PHP from JSON array

I'm trying to catch all objects in PHP from a JSON array, I need all the objects that will appear under ["Elements"]. So how would this be possible if I:
1.) Don't know the "name" of the object and don't know the content inside it.
2.) What I would like to achieve is to get the first objects value inside Elements, and then get the "content" inside of it, regardless of the names (there could be multiple objects)
Here is a var_dump of the JSON:
object(stdClass)#1 (1) {
["Canvas"]=>
array(1) {
[0]=>
["Elements"]=>
object(stdClass)#18 (2) {
["textHolder2"]=>
object(stdClass)#19 (1) {
["textContent"]=>
string(12) "Text to edit"
}
["textHolder1"]=>
object(stdClass)#20 (1) {
["textContent"]=>
string(12) "Text to edit"
}
}
}
}
}
Use foreach.
$json = json_decode( $input, true );
$elems = $json['canvas']['Elements'];
foreach( $elems as $key => $value ) {
echo "{$key} is an array/object:\n";
echo var_dump( $value );
}
You could use array_keys() if you need to know what keys are inside $value or you could another foreach loop, but I am assuming you will have at least some clue what keys could be in $value.

PHP __call adjusting array

I've got this weird bug which i'm hoping someone here can help me with, or at least explain why it is happening.
I'm using the __call method ;
public function __call($method, $params) {
var_dump($params);
echo '<br/><br/>';
}
I call this with per example:
$params = array('index' => 0, 'apikey' => 'aasdf');
$client->notAFunction($params)
This is a non-existent method, so it will go into __call with $method = notAFunction and my array in $params.
My expected output from __call would be;
array(2) { ["index"]=> int(0) ["apikey"]=> string(5) "aasdf" }
However, what I am getting as output is;
array(1) { [0]=> array(2) { ["index"]=> int(0) ["apikey"]=> string(5) "aasdf" } }
Now, I am aware of the fact that this is easily 'solved' by using $params[0] so i'm not looking for any answers like that.
I'm looking for;
Why does this happen?
Can I count on this to always happen?
Is there something I can do that makes __call receive the original array?
It is expected functionality. Argument $params in the __call method receives the array of parameters method got.
See http://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods for description.

Categories