Vardump to single variables in php - php

Lets say I have a function like this:
foreach ($links as $link) {
var_dump($link->nodeValue);}
And the output looks like this:
string(59) "I was "not" scared" string(32) "Hold my beer!" string(60) "üöä possible episode4" string(43)
So now I want the text behind the string() so I have its like this:
echo $first; // I was "not" scared
echo $second; // Hold my beer!
echo $third; // I hate strings3000
Only way I can think of is fetch var_dump with ob_start(); and substr is somehow...

(If you're on >= 7.0) the following should work for you:
$links = [
(object)['nodeValue' => 'i was "not" scared'],
(object)['nodeValue' => 'hold my beer'],
]; // just as an input example
list($first, $second) = array_column($links, 'nodeValue');
If on < 7.0 array_column can't pluck properties of objects so you'd have to gather it yourself with e.g.:
$values = array_map(function($node) {return $node->nodeValue;}, $links);
list($first, $second) = $values;

if I have correctly understood the question you can make a simple function similar to this :
function dumper($array){
foreach($array as $value){
foreach($value as $x){
echo gettype($x)."(".strlen($x).")". "\n";
echo $x. "\n";
}
}
}
and then :
$array = [
(object)['nodeValue' => 'sadasdadasd'],
(object)['nodeValue' => 'asdasdasdasdasd'],
(object)['nodeValue' => 'sadasdadasd'],
(object)['nodeValue' => 'asdasdasdasdasd'],
];
dumper($array);
That outputs:
string(11)
sadasdadasd
string(15)
asdasdasdasdasd
string(11)
sadasdadasd
string(15)
asdasdasdasdasd

Related

How correctly to process an arrays?

There are two arrays:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
The number of elements in the second array is less than or equal to the first array.
Sort out the first array and the second array, if the elements of the second array are contained at the end of the elements of the first array, sort the array in this form:
Array
(
[0] => w_ord
[1] => tech
[2] => care
[3] => k_ek
[4] => l_ol
[5] => wi_ld
[6] => re_gex
)
Important: the elements of the second array are never repeated, and can go in any order. If in the second element there is no end of the element of the first array, then set the value of the element of the first array.
I do this:
foreach($arr2 as $val) {
$strrepl[$val] = "_".$val;
}
foreach($arr1 as $key => $val) {
$arr3[$key] = str_replace(array_keys($strrepl), $strrepl, $val);
}
print_r($arr3);
But I'm not sure that this is the right approach, what will you advise?
Hmm, let's see ... purely functional 'cause you know :D
function ends($str) {
return function($suffix) use($str) {
return mb_strlen($str) >= mb_strlen($suffix)
&& mb_substr($str, mb_strlen($suffix) * -1) === $suffix;
};
}
$result = array_map(function($item) use($arr2) {
$filter = ends($item);
$suffixes = array_filter($arr2, $filter);
if (empty($suffixes)) {
return $item;
}
// This only cares about the very first match, but
// is easily adaptable to handle all of them
$suffix = reset($suffixes);
return mb_substr($item, 0, mb_strlen($suffix) * -1) . "_{$suffix}";
}, $arr1);
Surprisingly, this one was quite fun to execute.
Since you went very specific on end of the element, I decided to use RegEx for that.
Here is my approach:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
foreach ($arr2 as $find) {
foreach ($arr1 as $key => $element) {
$arr1[$key] = preg_replace('/' . $find . '$/', '_' . $find, $element);
}
}
For every element of the second array (since they are not repeated), I go through every element of the first array and check if the value can be found at the end of the element of the second array using the $ anchor from RegEx which forces it to look it from the end of the string.
This way the $arr1 will have exactly what you expect.
[Edit]
Following the scape suggestion from #aefxx and improving variable names.
You can use preg_grep which is regex on arrays.
This code will also make sure it can output more than one matching word from $arr1.
$arr1 = ['word', 'chord', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$keys=[];
foreach($arr2 as $val){
$matches = preg_grep("/.+" . preg_quote($val) . "/", $arr1);
$keys = array_merge($keys, array_keys($matches)); // save keys of matched words
foreach($matches as $key => $m) $new[$val][] = str_replace($val, "_$val", $arr1[$key]);
}
$new['unmatched'] = array_diff_key($arr1, array_flip($keys)); // add unmatched words
var_dump($new);
Output:
array(6) {
["ord"]=>
array(2) {
[0]=>
string(5) "w_ord"
[1]=>
string(6) "ch_ord"
}
["ek"]=>
array(1) {
[0]=>
string(4) "k_ek"
}
["ol"]=>
array(1) {
[0]=>
string(4) "l_ol"
}
["ld"]=>
array(1) {
[0]=>
string(5) "wi_ld"
}
["gex"]=>
array(1) {
[0]=>
string(6) "re_gex"
}
["unmatched"]=>
array(2) {
[2]=>
string(4) "tech"
[3]=>
string(4) "care"
}
}
https://3v4l.org/gfUea
You can try this.I think it is easy to understand :
$arr1=['word','tech','care','kek','lol','wild','regex'];
$arr2=['ord','ek','ol','ld','gex','ss'];
foreach($arr1 as $key=>$fullword){
foreach($arr2 as $substr){
$arr1[$key]=preg_replace('/' . $substr . '$/', '_' . $substr, $fullword,-1,$count);
if($count) break;
}
}
i go throught the array of fullword and as soon as i find a match i stop the search.
Another approach can be to create complex regex beforehand (using implode and preg_quote for safety) and use it for replacement inside array_map callback:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$regex = '/(' . implode('|', array_map('preg_quote', $arr2)) . ')$/';
$result = array_map(function ($word) use ($regex) {
return preg_replace($regex, '_$1', $word);
}, $arr1);
Here is the demo.

PHP Str_replace is not working in foreach loop

Here is my code.
I am trying to get inspect link for steam item. I have tried to use preg_replace but no luck either.
$API_link = sprintf("http://steamcommunity.com/id/*steamid*/inventory/json/730/2?trading=1");
$json = file_get_contents($API_link);
$json_output = json_decode($json);
$result = $json_output;
$link = array();
$id = array();
foreach($result->rgDescriptions AS $item){
$empty = array();
$newstring = $item->actions[0]->link;
if($newstring == NULL){
continue;
} else {
$empty['link'] = $newstring;
array_push($link, $empty);
}
}
foreach($result->rgInventory AS $inventory){
$empty = array();
if($inventory->instanceid == 0){
continue;
} else {
$empty['id'] = $inventory->id;
array_push($id, $empty);
}
}
$array = array_merge($id, $link);
foreach($array AS $final){
$assetid = "%assetid%";
echo str_replace($assetid, $final['id'], $final['link']);
}
}
But its not working. Please see if you can help.
As I can see you have array of arrays:
// bracket squares equivalent of array() keyword PHP >=v5.4
// here is
// $link = array(['link'=>'url'],['link'=>'url'])
// $id = array(['id'=>'id'],['id'=>'id'])
// result will be:
// array(['link']=>'url'],['link'=>'url'],['id'=>'id'],['id'=>'id'])
$array = array_merge($id, $link);
foreach($array AS $final){
// here is the first $final
// array('link'=>'url')
$assetid = "%assetid%";
// but here is we try to get
// 'id' and 'link'
echo str_replace($assetid, $final['id'], $final['link']);
}
I think it's some kind of mistake.
Ok, some test script:
<?php
$a = array( array('link'=>'hello1'), array('link'=>'hello2'));
$b = array( array('id'=>'id0'), array('id'=>'id1'));
$c = array_merge($a, $b);
var_dump($c);
result:
array(4) {
[0] =>
array(1) {
'link' =>
string(6) "hello1"
}
[1] =>
array(1) {
'link' =>
string(6) "hello2"
}
[2] =>
array(1) {
'id' =>
string(3) "id0"
}
[3] =>
array(1) {
'id' =>
string(3) "id1"
}
}
array_merge doesn't mix your associative arrays between them nether all nor particular item (I hope I explain it correct)
of course
foreach ($c as $item) {
var_dump($item);
}
will enumerate all the items one by one
array(1) {
'link' =>
string(6) "hello1"
}
array(1) {
'link' =>
string(6) "hello2"
}
array(1) {
'id' =>
string(3) "id0"
}
array(1) {
'id' =>
string(3) "id1"
}
and there is no array that has both of them (link and id) in the item
This script can't associate link and id properly, cause some of links can be skipped by continue, some of id also can be skipped. And it will be just a random list of available information. You can stuck in the next situation:
- $links has first 10 links
- $id has 3,4,5,7,9,11
It's just a list. Even if you have only this pure info (no other details), you can't properly associate it between of them by using shown source.
Here is minimum 1 simple solutions:
don't skip, don't merge, just add an empty array, and your final loop will be like this:
$assetid = "%assetid%";
for ($link as $key=>$final) {
if (count($final) && count($id[$key])) {
echo str_replace($assetid, $id[$key]['id'], $final['link']);
} else {
// some of needed arguments absent
}
}
Description not enough. Maybe try dump some variables?
foreach($array AS $final){
$assetid = "%assetid%";
//Check what is in $final
var_dump($final);
echo str_replace($assetid, $final['id'], $final['link']);
}

PHP array remove all arrays under keyword if found

I have 30 lines of text and explode into arrays separate by "\n". the result as follows:
[1]=> string(121) "In recent years, the rapid growth"
[2]=> string(139) "information technology has strongly enhanced computer systems"
[3]=> string(89) "both in terms of computational and networking capabilities"
[4]=> string(103) "-------------------------"
[5]=> string(103) "these novel distributed computing scenarios"
.
.
[30]=> string(103) "these computer safety applications. end"
in this case, i need to remove all arrays below "-------------" and produce output as follows:
[1]=> string(121) "In recent years, the rapid growth"
[2]=> string(139) "information technology has strongly enhanced computer systems"
[3]=> string(89) "both in terms of computational and networking capabilities"
any idea how to do this? thanks.
solution of the problem by Michael
$i = 0;
$new_arr = array();
while ($array[$i] != "-------------------------") {
// Append lines onto the new array until the delimiter is found
$new_arr[] = $array[$i];
$i++;
}
print_r($new_arr);
Best solution:
Use array_search() and then truncate the array with array_splice():
$key = array_search("-------------------------", $array);
array_splice($array, $key);
Obvious solution:
You can loop over it copying the output to a new array. First example that comes to mind:
$i = 0;
$new_arr = array();
while ($array[$i] != "-------------------------") {
// Append lines onto the new array until the delimiter is found
$new_arr[] = $array[$i];
$i++;
}
print_r($new_arr);
for example
function getMyArray( $array ){
$myArray = array();
foreach( $array as $item ){
if ( $item == '-------------------------' ){ return $myArray; }
$myArray[] = $line;
}
return $myArray'
}
array_search
and unset
you can also use array_slice
You can use array_search to find the key of where its located.
from PHP.net:
<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
?>
Once you have the key, you could do:
<?php
while($key < count($array) )
{
$array = unset($array[$key]);
$key++;
}
?>
foreach($array as $key => $value)
{
if($value == '-------------')
break;
else
$new_array[$key]=$value;
}

change key of the multi-array

Have an array:
$a =array[
"param1"=>[]
"param2"=>[]
"param3"=>[]
]
function def($param){
return $param.date();
}
want return a new array
$a =array[
def(param1)=>[]
def(param2)=>[]
def(param3)=>[]
]
anybody know how to do this?
Do you mean something like this?
This is a pretty lengthy (and dirty) suggestion and there's probably a better way using one of PHP's array methods, but here goes:
$array = array('123' => 'should be 6', '14' => 'should be 5', '12' => 'should be 3');
$new_array = array();
foreach ($array as $key => $val) {
$key_exp = str_split($key);
$new_key = 0;
foreach ($key_exp as $key_int) $new_key += $key_int;
$new_array[$new_key] = $val;
}
Gives this output as expected:
array(3) {
[6]=>
string(11) "should be 6"
[5]=>
string(11) "should be 5"
[3]=>
string(11) "should be 3"
}
Note that you may, and probably will, run into key collisions using this method.
Like so:
$out_array = array_fill_keys(array_map(function($in) {
// do stuff you need
return $out;
}, array_keys($in_array)), array());

Simple PHP Recursion Test Failing

I am attempting a basic recursion to create multi-dimensional arrays based on the values of an inputed array.
The recursion works by checking for a value we shall call it "recursion" to start the loop and looks for another value we'll call it "stop_recursion" to end.
Basically taking this array
array('One', 'Two', 'recursion', 'Three', 'Four', 'Five', 'stop_recursion', 'Six', 'Seven')
And making this array
array('One', 'Two', array('Three', 'Four', 'Five'), 'Six', 'Seven')
The code I have for it so far is as follows
function testRecrusion($array, $child = false)
{
$return = array();
foreach ($array as $key => $value) {
if ($value == 'recursion') {
unset($array[$key]);
$new = testRecrusion($array, true);
$array = $new['array'];
$return[] = $new['return'];
} else {
if ($value == 'stop_recursion') {
unset($array[$key]);
if ($child) {
return array('return' => $return, 'array' => $array);
}
} else {
unset($array[$key]);
$return[] = $value;
}
}
}
return $return;
}
But the output from that is
Array
(
[0] => One
[1] => Two
[2] => Array
(
[0] => Three
[1] => Four
[2] => Five
)
[3] => Three
[4] => Four
[5] => Five
[6] => Six
[7] => Seven
)
I guess the real question is...will an array values continuously loop through the first values given from the initial call or once the new array is returned and set will it loop through that new array. I know the answer is basically right here saying that yes it will continue the old array value, but shouldn't this work vice-versa?
Any help will be appreciated :)
------------ edit -------------------
I might as well add that while I can perform this action using a much simpler method, this needs to be recursively checked since this will be ported to a string parser that could have a infinite number of child arrays.
When you return inside the recursion, you need to return both the inner array and the index from which to continue searching for elements so that you don't look at the same element twice. Try this instead:
function testRecursionImpl($array, $i)
{
$return = array();
for (; $i < sizeof($array); ++$i) {
if ($array[$i] == 'recursion') {
$new = testRecursionImpl($array, $i + 1);
$return[] = $new[0];
$i = $new[1];
} else if ($array[$i] == 'stop_recursion') {
return array($return, $i);
} else {
$return[] = $array[$i];
}
}
return array($return, $i);
}
function testRecursion($array)
{
$result = testRecursionImpl($array, 0);
return $result[0];
}
The problem you have in the code above is that you correctly detect when you should call this function recursively but once it finishes running and you append the results to output array you just pick next element (which is the first element that recursive call will get) and append it to output array. What you probably want to do is when you detect that you should run your function recursively you should skip all other characters until you find your stop word (stop_recursion). Obviously the problem will become harder if you allow multi-level recursion then you may need to even skip some stopwords because they could be from the different level call.
Still I don't know why you want such a feature. Maybe you would explain what are you trying to achieve. I'm pretty sure there's another, simpler way of doing it.
Rather than helping with your homework, I would suggest you start with getting rid of this line:
foreach ($array as $key => $value) {
You should just pass in your array, and check for being at the end of the array, since it can't really be infinite, to know when you are done.
Let me give it a try
function testRecursion($arr){
$return = array();
$recurlevel = 0;
foreach ($arr as $v) {
if($v == 'stop_recursion'){
$recurlevel--;
}
if($recurlevel == 0){
if(isset($current)){
$return[] = testRecursion($current);
unset($current);
}else{
if($v != 'recursion'){
$return[] = $v;
}
}
}else{
if(!isset($current)){
$current = array();
}
$current[] = $v;
}
if($v == 'recursion'){
$recurlevel++;
}
}
return $return;
}
Alright nicely done. This will help even if the recursion and stop_recursion are nested in another. See example:
code.php:
<pre><?php
function testRecursion($arr){
$return = array();
$recurlevel = 0;
foreach ($arr as $v) {
if($v == 'stop_recursion'){
$recurlevel--;
}
if($recurlevel == 0){
if(isset($current)){
$return[] = testRecursion($current);
unset($current);
}else{
if($v != 'recursion'){
$return[] = $v;
}
}
}else{
if(!isset($current)){
$current = array();
}
$current[] = $v;
}
if($v == 'recursion'){
$recurlevel++;
}
}
return $return;
}
$a = array('One', 'Two', 'recursion', 'Three', 'recursion', 'Four' , 'stop_recursion', 'Five', 'stop_recursion', 'Six', 'Seven');
var_dump(testRecursion($a));
?>
Browser output:
array(5) {
[0]=>
string(3) "One"
[1]=>
string(3) "Two"
[2]=>
array(3) {
[0]=>
string(5) "Three"
[1]=>
array(1) {
[0]=>
string(4) "Four"
}
[2]=>
string(4) "Five"
}
[3]=>
string(3) "Six"
[4]=>
string(5) "Seven"
}
Since your question for the recursive solution has already been answered ...might I offer a stack-based solution?
$x = array('a', 'b', 'recursion', 'cI', 'cII', 'cIII', 'recursion', 'cIV1', 'cIV2', 'cIV2', 'stop_recursion', 'stop_recursion', 'd', 'e');
$result = array();
$stack = array(&$result);
foreach($x as $e) {
if ( 'recursion'===$e ) {
array_unshift($stack, array());
$stack[1][] = &$stack[0];
}
else if ( 'stop_recursion'===$e ) {
array_shift($stack);
}
else {
$stack[0][] = $e;
}
}
var_dump($result);
prints
array(5) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
array(4) {
[0]=>
string(2) "cI"
[1]=>
string(3) "cII"
[2]=>
string(4) "cIII"
[3]=>
array(3) {
[0]=>
string(4) "cIV1"
[1]=>
string(4) "cIV2"
[2]=>
string(4) "cIV2"
}
}
[3]=>
string(3) "d"
[4]=>
string(5) "e"
}

Categories