I am fetching values from online using curl from given url working fine, but here the problem is, giving combined string like - first url had one value returning and next url returning with 5 values so total six values displaying as like this, "testdata1testdata2testdata3testdata4testdata5testdata6testdata7" i need to insert these data to mysql it is storing like string how to separate by comma.
function data($urls,$v)
{
foreach ($urls as $url => $key)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $key);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
$str = curl_exec($curl);
curl_close($curl);
$html= str_get_html($str);
foreach($html->find('.name') as $element)
{
$grab = $element->innertext;
$sql = $this->db->prepare("UPDATE table SET word='$grab' where url='$v[$url]'");
}
}
}
UPDATE
You wrote in comments, that there are no numbers in the variables past. In that case it is impossible to guess where the delimeters should be unless you know i.e.
the size of each parameter (maybe it is constant?)
have got array of ALL possible variables?
know something more about the variables structure?
If You don't, the answer is: You can't, sorry. As Shah Rukh suggested in comments, try to use i.e. json to pass the parameters to another page / subpage / script.
If every variable is ended with a number, you can try this solution:
(I assumed that every variable passed is ended up with a number, so You must be really careful and be sure that this is the exact format, that the data will always be sent in).
function every($matches) {
return $matches[1].',';
}
$input = 'testdata1testdata2testdata3testdata4testdata5testdata6testdata7';
$input = preg_replace_callback( "|(\d+)|", "every", $input);
$input = explode(',', rtrim($input, ","));
print_r($input);
Will print out:
Array
(
[0] => testdata1
[1] => testdata2
[2] => testdata3
[3] => testdata4
[4] => testdata5
[5] => testdata6
[6] => testdata7
)
I hope it helps, however I think that you should change some logic of your application, and send the data between pages in a more user friendly format as json for example. Best regards!
PS. If You want to get rid of "test", you can do for example:
foreach ($input as $key => $value) $input[$key] = substr($value, 4);
But remember to be careful when modifying arrays at the same time you are iterating them through.
Related
I am trying to send JSON information from Python to PHP through a JSON file data.json, based on the content of the Stack Overflow question/answer here. I am running this code all on an Apache web server on Raspberry Pi 3.
Here is my code:
Python
import sys, json, random # I know I don't need sys and random to run this, but I was using these in my previous code.
data = {'fruit':['oranges', 'apples', 'peaches'], 'age':12}
with open('data.json', 'w') as outfile:
json.dump(data, outfile)
When run, this program worked fine and exited with code 0.
JSON file
{"age": 12, "fruit": ["oranges", "apples", "peaches"]}
As you can see, my Python worked perfectly and the output is identical to the data variable in my python code. On second thought, the order is backward, although I don't think this matters.
PHP
Now, this is where the problem is:
<?php
$string = file_get_contents("data.json");
$json_a = json_decode($string, true);
$arr = array();
foreach ($json_a as $key) {
array_push($arr,json_decode($key[0],true));
}
echo json_encode($arr);
?>
When run, the program exited with code 0 but outputed:
[null,null]
Does anyone have an idea why this is, or is this just the way JSON works?
The original code with issues:
<?php
$string = file_get_contents("data.json");
$json_a = json_decode($string, true);
$arr = array();
foreach ($json_a as $key) {
// No need to use json_decode again
// as it is already converted to an array
// by the inital json decode statement
array_push($arr,json_decode($key[0],true));
}
echo json_encode($arr);
?>
Pretty printed PHP Array which is stored inside $json_a:
Array
(
[age] => 12
[fruit] => Array
(
[0] => oranges
[1] => apples
[2] => peaches
)
)
The problem:
In the original script, json_decode was used on an already decoded variable/array which returned nothing and hence null was appended to your list.
Code walkthrough:
During the first iteration of the foreach loop,
$key will have the value 12 - which is a string
During the second iteration of the foreach loop,
$key will have the value - which is an Array
Array
(
[0] => oranges
[1] => apples
[2] => peaches
)
The corrected code for printing all the fruits:
<?php
$string = file_get_contents("data.json");
$json_a = json_decode($string, true);
$arr = array();
foreach ($json_a['fruit'] as $key) {
array_push($arr,$key);
}
echo json_encode($arr);
?>
The above snippet returns ["oranges","apples","peaches"]
I'm using Laravel and am attempting to write an artisan command that accepts an argument, $content, that then needs to be transposed to an array. For example:
// An example of a value that is being passed in from the CLI and stored as $content
$content = "['div']['div'][0]['h2']['a']";
To clarify, $content is then being passed in as a function argument where it will be used to pull out the values from the actual result set. In other words, I'm receiving a response from an API and $content is the path to the values that I need to pull out of the response. For example, the hard coded version of the implementation looks like:
$result = $report['div']['div'][0]['h2']['a'];
Now, $result contains the values that I need to process. However, I'm trying to make this dynamic so I don't repeat myself each time I add in a new data source to check for reports. Currently, I have 4 functions each with hard-coded paths to the desired result; the goal is to make it so that I can pass in an argument that contains the path to the desired values and refactor my code so I only have the one function which accepts the path to the values as an argument.
I hope that clarifies the end-goal and why I'm only referencing keys, not a value.
Anyway, back to the problem at hand. I've attempted different variations of the following:
// Attempting to parse the string into an array
$arr = explode("]", trim(str_replace("[","",$content), "]"));
This results in the following array:
array (size=5)
0 => string ''div'' (length=5)
1 => string ''div'' (length=5)
2 => string '0' (length=1)
3 => string ''h2'' (length=4)
4 => string ''a'' (length=3)
But, what I need is for the array to be formatted like the following:
$array = ['div']['div'][0]['h2']['a']
I attempted to do a foreach($array as $element) over $arr and do an array_push for each element, but that resulted in the same output as $arr.
How can I loop over the string and parse it into an array? Additionally, I need 0 to remain as an index, and not be type casted as a string. And, one last note, the value of $content will be completely different each time, so I need it to be quite flexible. The only part that will remain constant is the [ and ] will always encapsulate the keys.
I'd love to hear how others would solve this seemingly trivial problem (I've taken a few years off from programming and apparently have forgotten more than I care to admit ;) ). I honestly thought that the str_replace and explode was going to provide me the result I was expecting...
But, after re-reading the php.net/explode doc, it's always going to cast each element as a string (thus overriding my 0 index), and I have no idea how to turn it into a nested array, instead of a simple, flat array.
I look forward to your advice and insight. Thanks.
EDIT:
Including the function that is making use of the arguments to help provide some greater clarity.
private function yql_check_website($url, $xpath, $content) {
require_once('../vendor/OAuth.php');
$statement = "select * from html where url='{$url}' and xpath='{$xpath}' ";
$cc_key = $this->key;
$cc_secret = $this->secret;
$url = "http://query.yahooapis.com/v1/public/yql";
$args = array();
$args["q"] = $statement;
$args["format"] = "json";
$consumer = new OAuthConsumer($cc_key, $cc_secret);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL,"GET", $url, $args);
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
$url = sprintf("%s?%s", $url, OAuthUtil::build_http_query($args));
$url .= "&env=store://datatables.org/alltableswithkeys";
$ch = curl_init();
$headers = array($request->to_header());
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$rsp = curl_exec($ch);
$report = json_decode($rsp, true);
// Dynamically inspect the $report object for the xpath content
$result = $report . $content;
unset($report);
return $result;
}
So, $report contains the entire API response, but the only thing I need is the content that is provided in $report['div']['div'][0]['h2']['a'] (for this example, at least, the path is different for each report that I'm scraping). So, the reason I'm trying to convert the command line argument into an array is so that it can be used in the above code where $content is being called in order to navigate the API's response and return the values from that segment.
I hope that makes more sense. And, if there is a better way to achieve this end-goal, feel free to mention it. I may be taking the wrong approach...
Laravel has a few methods for array access that provide "dot" access to arrays, including array_get. The method prototype looks like this:
function array_get(array $array, string $key, mixed $default = null)
So, in your case, you could write:
$results = array_get($report, "div.div.0.h2.a");
You could just use preg_match_all here..
$content = "['div']['div'][0]['h2']['a']";
$expression = /\['([a-zA-Z0-9]+)\']/;
$results = preg_match_all( $expression, $content, $matches );
print_r( $matches );
If you have to have the array be like what you're saying, you could do something like this (for starters - this is a little ugly though as it is...)
// array( ['div']['div'][0]['h2']['a']
// visualizing...
// array( 'div' => array ( 'div' => 'array( "0" => array( "h2" => array( "a") ) ) ) );
function createDepth( $source, $currentKey, $nextDepth = null ) {
if( !is_array( $nextDepth ) ) {
$source[] = array( $currentKey => $nextDepth );
} else {
$nextKey = array_shift( $nextDepth );
$source[] = createDepth( array( $currentKey => array() ), $nextKey, $nextDepth );
}
return source;
}
// Edit: doh, unset the first key..
unset( $matches[0] );
// Continue from here.
$currentKey = array_shift( $matches );
$holder = array();
$final = createDepth( $holder, $currentKey, $matches);
print_r( $final );
Note: All the above is untested...
Is this what you want ?
$str = "['div']['div'][0]['h2']['a']";
$str = preg_split('/]\[/', substr(str_replace("'", "", $str), 1, -1));
print_r($str);
Array (
[0] => div
[1] => div
[2] => 0
[3] => h2
[4] => a
)
I am new PHP question and I am trying to create an array from the following string of data I have. I haven't been able to get anything to work yet. Does anyone have any suggestions?
my string:
Acct_Status=active,signup_date=2010-12-27,acct_type=GOLD,profile_range=31-35
I want to dynamically create an array called "My_Data" and have id display something like my following, keeping in mind that my array could return more or less data at different times.
My_Data
(
[Acct_Status] => active
[signup_date] => 2010-12-27
[acct_type] => GOLD
[profile_range] => 31-35
)
First time working with PHP, would anyone have any suggestions on what I need to do or have a simple solution? I have tried using an explode, doing a for each loop, but either I am way off on the way that I need to do it or I am missing something. I am getting something more along the lines of the below result.
Array ( [0] => Acct_Status=active [1] => signup_date=2010-12-27 [2] => acct_type=GOLD [3] => profile_range=31-35} )
You would need to explode() the string on , and then in a foreach loop, explode() again on the = and assign each to the output array.
$string = "Acct_Status=active,signup_date=2010-12-27,acct_type=GOLD,profile_range=31-35";
// Array to hold the final product
$output = array();
// Split the key/value pairs on the commas
$outer = explode(",", $string);
// Loop over them
foreach ($outer as $inner) {
// And split each of the key/value on the =
// I'm partial to doing multi-assignment with list() in situations like this
// but you could also assign this to an array and access as $arr[0], $arr[1]
// for the key/value respectively.
list($key, $value) = explode("=", $inner);
// Then assign it to the $output by $key
$output[$key] = $value;
}
var_dump($output);
array(4) {
["Acct_Status"]=>
string(6) "active"
["signup_date"]=>
string(10) "2010-12-27"
["acct_type"]=>
string(4) "GOLD"
["profile_range"]=>
string(5) "31-35"
}
The lazy option would be using parse_str after converting , into & using strtr:
$str = strtr($str, ",", "&");
parse_str($str, $array);
I would totally use a regex here however, to assert the structure a bit more:
preg_match_all("/(\w+)=([\w-]+)/", $str, $matches);
$array = array_combine($matches[1], $matches[2]);
Which would skip any attributes that aren't made up of letters, numbers or hypens. (The question being if that's a viable constraint for your input of course.)
$myString = 'Acct_Status=active,signup_date=2010-12-27,acct_type=GOLD,profile_range=31-35';
parse_str(str_replace(',', '&', $myString), $myArray);
var_dump($myArray);
I don't know how to make this working. I want to make arrays from URL:
index.php?address=someaddress&telephone=12345&customer=Customer Name&p_name[0]=ProductOne&p_name[1]=ProductTwo&p_price[0]=1&p_price[1]=10&p_name[2]...
There is an api, which is working like this:
$api‐>addItem(array(
'name' => 'ProductOne',
'price' => '123',
));
$api‐>addItem(array(
'name' => 'ProductTwo',
'price' => '32',
));
Is there any way to make arrays like this (=api request $api->addItem(array) from the URL? $api‐>addItem(array can be used multiple times.
EDIT: Thanks dqhendricks and Rocket for pointing out that you can use parse_str() to do the same thing.
$q = parse_str(parse_url($url, PHP_URL_QUERY));
Or you could use this (the long way):
function parse_query($var) {
$var = parse_url($var, PHP_URL_QUERY);
$var = html_entity_decode($var);
$var = explode('&', $var);
$arr = array();
foreach($var as $val) {
$x = explode('=', $val);
$arr[$x[0]] = $x[1];
}
unset($val, $x, $var);
return $arr;
}
Use like this:
$url = "http://someurl.com/click?z=26&a=761";
print_r(parse_query($url));
Do you have control over the URL? If so, I'd change how you send your values.
Instead of:
name1=ProductOne&price1=123&name2=ProductTwo&price2=32
I'd use:
name[]=ProductOne&price[]=123&name[]=ProductTwo&price[]=32
The [] turn them into arrays, meaning $_GET['name'] is now an array. then you can foreach over it.
foreach($_GET['name'] as $k=>$v){
$api->addItem(array(
'name' => $v,
'price' => $_GET['price'][$k]
));
}
// extract the query from the url string
$url = parse_url('sample.php?name1=ProductOne&price1=123&name2=ProductTwo&price2=32', PHP_URL_QUERY);
// process into array so that first element is a key, and second element is a value
parse_str($url, $output_array);
// now $output_array contains the query's variables.
The bigger question is why would you want to do this when these variables are already contained in $_GET?
sample.php?name[]=Product1&name[]=Product2
Then in your PHP, you can see:
print_r($_GET['name']);
I'm not sure if I understood you right, but if what you're looking for is converting a querystring to an array you can user the pares_str function. in order to get only the querystring from a url you can use the parse_url function
$url = "sample.php?some_var=someval&s=4&bla=bla";
$url_parts = parse_url($url);
$qs = $url_parts["query"];
$params = array();
parse_str($qs,$params);
var_dump($params);
Like dqhendricks suggested, would it not pay to just use the raw gets and then append them to an array. I am assuming that you will always know what will be in the URL
$array_of_gets = array("address" => $_GET['address'],"telephone" => $_GET['telephone']);
and so on...
This question already has answers here:
How create an array from the output of an array printed with print_r?
(11 answers)
Closed 10 years ago.
How can i create variable from it's print_r output ? In other words, i'd like to know if something similar to my fictive var_import function exists in php ? var_import would be the inverse of var_export
He is a use case:
$a = var_import('Array ( [0] => foo [1] => bar )');
$output = var_export($a);
echo $output; // Array ( [0] => foo [1] => bar )
If such a function does not exist, is there a tool (or online tool) to do this ?
I am also interested to do the same with var_dump output.
EDIT: The variable is only available as a print_r output (string). To clarify what i need, imagine the folowing situation: someone posts a some sample on the internet somewhere with a print_r output. To test his code, you need to import his print_r variable into your code. This is an example where var_import would be usefull.
Amusingly the PHP manual contains an example that tries to recreate the original structure from the print_r output:
print_r_reverse()
http://www.php.net/manual/en/function.print-r.php#93529
However it does depend on whitespace being preserved. So you would need the actual HTML content, not the rendered text to pipe it back in.
Also it doesn't look like it could understand anything but arrays, and does not descend. That would be incredibly difficult as there is no real termination marker for strings, which can both contain newlines and ) or even [0] and => which could be mistaken for print_r delimiters. Correctly reparsing the print_r structure would be near impossible even with a recursive regex (and an actual parser) - it could only be accomplished by guesswork splitting like in the code linked above.. (There are two more versions there, maybe you have to try them through to find a match for your specific case.)
Why don't you use var_export instead ?
var_export(array(1, 2, 3)); // array(1, 2, 3)
You can import var_export's output with eval(), however I would recommend you to avoid this function as much as possible.
The following functions are better for exporting and importing variables:
serialize() and unserialize():
$string = serialize(array(1, 2, 3));
$array = unserialize($string); // array(1, 2, 3);
Or json_encode() and json_decode():
$string = json_encode(array(1, 2, 3));
$array = json_decode($string);
You can wrap it in an output buffer:
ob_start();
print_r(array(1,2,3));
$arr = ob_get_clean();
echo $arr;
Ok so I misunderstood the first question. I think I have another solution which actually does answer your question:
<?php
$ar = array('foo','bar');
$p = print_r($ar, true);
$reg = '/\[([0-9]+)\] \=\> ([a-z]+)/';
$m = preg_match_all($reg, $p, $ms);
$new_ar = $ms[2];
echo "Your wanted result:\n";
print_r($new_ar);
If you want to import a var_export()'s variable, you can run the eval() function.
Or if you save the contents into a file (with a return statement), you can use the return value of include() or require().
But I would rather use serialize() and unserialize() or json_encode() and json_decode().
define('EXPORT_JSON', 1);
define('EXPORT_SERIALIZE', 2);
function exportIntoFile($var, $filename, $method=EXPORT_JSON)
{
if ( $method & EXPORT_JSON )
file_put_contents( $filename, json_encode($var) );
else if ($method & EXPORT_SERIALIZE)
file_put_contents( $filename, serialize($var) );
}
function importFromFile($filename, $method=EXPORT_JSON)
{
if ( $method & EXPORT_JSON )
return json_decode( file_get_contents($filename) );
else if ($method & EXPORT_SERIALIZE)
return unserialize( file_get_contents($filename) );
}
I'm not good at regex to code the final trash removal. Here is how far I could get though:
$str = 'Array ( [0] => foo [1] => bar [2] => baz)';
$t1 = explode('(', $str);
$t2 = explode(')', $t1[1]);
$t3 = explode(' => ', $t2[0]);
unset($t3[0]);
print_r($t3);
output:
Array
(
[1] => foo [1]
[2] => bar [2]
[3] => baz
)