I've spent a long time on this problem, and I cannot for the life of me figure it out. Any help will be much appreciated!
I have an array of strings, which I am using to get information from, i.e. the month of an event is hidden within the url (the string), and I want to cycle through all the urls and get the month, and other data out and make each data-piece it's own array.
Here's the deal, I can do it twice successfully, but the third time I try to create an array, it breaks down.
This code works:
$months = array();
$times = array();
foreach ($ticketsLinks as $ticketsLink){
//CREATE VENUE ARRAY
// Delete all the way up to "-tickets-"
$findMeA = '-tickets-';
$posA = strpos($ticketsLink, $findMeA);
$posA = $posA + 9;
$venue = substr($ticketsLink, $posA);
// Find the first number in the string - delete everything after that.
$lengthA = strlen($venue);
$parts = str_split($venue);
$first_num = -1;
$num_loc = 0;
foreach ($parts AS $a_char) {
if (is_numeric($a_char)) {
$first_num = $num_loc;
break;
}
$num_loc++;
}
$posB = -$lengthA + $num_loc - 1;
$venue = substr($venue, 0, $posB);
// Replace dashes with spaces.
$venue = str_replace("-"," ",$venue);
//Add value to venue's array
$venues[] = $venue;
// CREATE TIME ARRAY
$pos = strrpos($ticketsLink, '-');
$pos = strlen($ticketsLink) - $pos - 1;
$time = substr($ticketsLink, -$pos);
$pos = strpos($time, '/');
$time = substr($time, 0, $pos);
$times[] = $time;
}
This code does not:
$months = array();
$times = array();
$years = array();
foreach ($ticketsLinks as $ticketsLink){
//CREATE VENUE ARRAY
// Delete all the way up to "-tickets-"
$findMeA = '-tickets-';
$posA = strpos($ticketsLink, $findMeA);
$posA = $posA + 9;
$venue = substr($ticketsLink, $posA);
// Find the first number in the string - delete everything after that.
$lengthA = strlen($venue);
$parts = str_split($venue);
$first_num = -1;
$num_loc = 0;
foreach ($parts AS $a_char) {
if (is_numeric($a_char)) {
$first_num = $num_loc;
break;
}
$num_loc++;
}
$posB = -$lengthA + $num_loc - 1;
$venue = substr($venue, 0, $posB);
// Replace dashes with spaces.
$venue = str_replace("-"," ",$venue);
//Add value to venue's array
$venues[] = $venue;
// CREATE TIME ARRAY
$pos = strrpos($ticketsLink, '-');
$pos = strlen($ticketsLink) - $pos - 1;
$time = substr($ticketsLink, -$pos);
$pos = strpos($time, '/');
$time = substr($time, 0, $pos);
$times[] = $time;
// CREATE YEAR ARRAY
$pos = strrpos($ticketsLink, '-');
$pos = strlen($ticketsLink) - $pos - 1;
$year = substr($ticketsLink, -$pos);
$pos = strpos($year, '/');
$year = substr($year, 0, $pos);
$years[] = $year;
}
For the purposes of this example, I kept the code to get the year string and the time string exactly the same to show that that wasn't the problem. I've gone through the above code and tried to debug it - the only thing that's making it not work is when I push the year variable to the years array.
--- UPDATED TO INCLUDE NEW INFORMATION -----
Unfortunately, breaking apart the URL to get the requisite information is the best way to do this - the URLs are coming from a CSV feed.
So, after the first foreach, then just for a test, I run a foreach loop through the $years array -
foreach($years as $year){
echo $year;
}
Eventually, the $years array will be passed to a mySQL database, but for now, I just want to make sure I'm processing the URL correctly. The resultant loop should look something like this:
2014
2015
2014
2016
Instead, I get nothing, and all the code after the first foreach (where I'm breaking down the URL), doesn't run. I have an echo at the bottom that echos "This code works!", and it doesn't print to the screen when I try to push values to the $years array.
Related
I was hoping to convert a single integer variable (coming in from a POST parameter) into a list, within a range of the original number, for example +/-3, using PHP.
So if var = 5
using PHP, output is = 2,3,4,5,6,7,8
or if var = 17
output is = 14,15,16,17,18,19,20
This is early guesswork, but I was thinking something like this:
<?php
$single = $_POST['number'];
$mc = $single - 3;
$mb = $single - 2;
$ma = $single - 1;
$pa = $single + 1;
$pb = $single + 2;
$pc = $single + 3;
$list = [$mc, $mb, $ma, $single, $pa, $pb, $pc,]
echo $list
?>
But it is just printing 'Array',
New to PHP, feel like I am overlooking a lot of things. Is it possible to assemble an array like this? Is there a quicker way to do what I'm trying?
Was hoping to do more like +/-30 .. was hoping there might be a shortcut / function that could help?
You can use range for this.
<?php
$num = filter_input(INPUT_GET, 'num', FILTER_VALIDATE_INT);
$range = 3;
if($num !== false) {
$result = range($num-$range, $num+$range);
echo implode(',', $result);
}
Output when (num is 2 and range is 3):
-1,0,1,2,3,4,5
Just use implode function after that.
$list = [$mc, $mb, $ma, $single, $pa, $pb, $pc];
echo implode(',', $list);
If you want to extend it for variable range too.
$single = 17;
$range = 3;
$data = range($single - $range, $single + $range);
echo implode(',', $data);
Was hoping to do more like +/-30 .. was hoping there might be a shortcut / function that could help?
Yes, use a loop. Because you know the range you want, you can use a for loop:
NOTE: This code works with negative numbers, too.
$range = 3; // your given range
$value = (int)$_POST['number'];
$result = [];
$result[] = $value;
for ($i = 1; $i <= $range; $i++){
$result[] = $value - $i ;
$result[] = $value + $i;
}
// Sort array and then output:
sort($result, SORT_NUMERIC);
print implode(', ', $result);// outputs a sorted list of values
// Value = -2
// -5, -4, -3, -2, -1, 0, 1
//
// Value = 5
// 2, 3, 4, 5, 6, 7, 8
I am trying to find two indicies given two datetimes and an array of datetimes. I want to find the index of the respective two dates, where the time is closest to what is available in the datetime array. Here is what I tried:
$label = array();
$price = array();
$linePoints = array();
$ind = 0;
// format example $oT = '2018-05-05 12:05:55'
$checkOpen = strtotime($oT);
$checkClose = strtotime($cT);
while ($run = mysqli_fetch_object($query)){
$p = $run->price;
$l = $run->time;
array_push($price, $p);
array_push($label, $l);
// format example: $l = '2018-05-05 12:05:52'
$check = strtotime($l);
$dif = abs($checkOpen - $check);
if($dif < 10){
array_push($linePoints, $ind);
}
$dif = abs($checkClose - $check);
if($dif < 10){
array_push($linePoints, $ind);
}
$ind = $ind +1;
}
The problem with this approach is, that this approach may bring multiple matches since the time difference is computed as milliseconds I guess? In the end, I only want two have two indicies in the array $linePoints. Any idea on how to achieve this? Thx!
For this job the DB is much faster than PHP. You'll gain simplicity and performance.
if($run = mysqli_query($con,"SELECT event_id FROM Table ORDER BY ABS( DATEDIFF( time, $checkOpen ) ) LIMIT 1")){
$price1 = $run->price;
$label1 = $run->label
}
if($run = mysqli_query($con,"SELECT event_id FROM Table ORDER BY ABS( DATEDIFF( time, $checkClose ) ) LIMIT 1")){
$price2 = $run->price;
$label2 = $run->label
}
Here you're, then. Your code is fixed now.
$label = array();
$price = array();
$linePoints = array();
$ind = 0;
// format example $oT = '2018-05-05 12:05:55'
$checkOpen = strtotime($oT);
$checkClose = strtotime($cT);
while ($run = mysqli_fetch_object($query)){
$p = $run->price;
$l = $run->time;
array_push($price, $p);
array_push($label, $l);
// format example: $l = '2018-05-05 12:05:52'
$check = strtotime($l);
$dif = abs($checkOpen - $check);
if($dif < abs ($checkOpen - $linePoints[0]){
$linePoints[0] = $ind);
}
$dif = abs($checkClose - $check);
if($dif < $checkClose - $linePoints[1]){
$linePoints[1] = $ind;
}
$ind = $ind +1;
}
I want to parse and expand the given strings in PHP.
From
0605052&&-5&-7&-8
0605052&&-4&-7
0605050&&-2&-4&-6&-8
To
0605052, 0605053 ,0605054 ,0605055, 0605057, 0605058
0605052,0605053,0605054,0605057
0605050,0605051,0605052,0605054,0605056,0605058
can someone help me with that? thanks in advance!
Your question is not very clear, but I think you mean a solution like this:
Edited: Now the hole ranges were shown and not only the specified numbers.
<?php
$string = "0605052&&-5&-7&-8";
$test = '/^([0-9]+)\&+/';
preg_match($test, $string, $res);
if (isset($res[1]))
{
$nr = $res[1];
$test = '/\&\-([0-9])/';
preg_match_all($test, $string, $res);
$result[] = $nr;
$nrPart = substr($nr, 0, -1);
$firstPart = substr($nr, -1);
if (isset($res[1]))
{
foreach ($res[1] as &$value)
{
if ($firstPart !== false)
{
for ($i=$firstPart+1; $i<=$value; $i++)
{
$nr = $nrPart . $i;
$result[] = $nr;
}
$firstPart = false;
}
else
{
$nr = $nrPart . $value;
$result[] = $nr;
$firstPart = $value;
}
}
}
var_dump($result);
}
?>
This delivers:
result[0] = "0605052"
result[1] = "0605053"
result[2] = "0605054"
result[3] = "0605055"
result[4] = "0605057"
result[5] = "0605058"
I think a multi step approach is the best thing to do here.
E.g. take this as an example 0605052&&-5&-7&-8:
Split at -. The result will be 0605052&&, 5&, 7&, 8
The first result 0605052&& will help you create your base. Simply substring the numbers by finding first occurence of & and substring to the next to last number. Result will be 060505. You will also need the last number, so get it as well (which is 2 in this case).
Get the remaining ends now, all \d& are simple to get, simply take the first character of the string (or if those can be more than one number, use substring with first occurence of & approach again).
The last number is simple: it is 8.
Now you got all important values. You can generate your result:
The last number from 2., all numbers from 3. and the number from 4. together with your base are the first part. In addition, you need to generate all numbers from the last number of 2. and the first result of 3. in a loop by a step of 1 and append it to your base.
Example Code:
<?php
$str = '0605052&&-5&-7&-8';
$split = explode('-', $str);
$firstAmpBase = strpos($split[0], '&');
$base = substr($split[0], 0, $firstAmpBase - 1);
$firstEnd = substr($split[0], $firstAmpBase - 1, 1);
$ends = [];
$firstSingleNumber = substr($split[1], 0, strpos($split[1], '&'));
for ($i = $firstEnd; $i < $firstSingleNumber; $i++) {
array_push($ends, $i);
}
array_push($ends, $firstSingleNumber);
for ($i = 2; $i < count($split) - 1; $i++) {
array_push($ends, substr($split[$i], 0, strpos($split[$i], '&')));
}
array_push($ends, $split[count($split) - 1]);
foreach ($ends as $end) {
echo $base . $end . '<br>';
}
?>
Output:
0605052
0605053
0605054
0605055
0605057
0605058
Having this URL string:
$URL = "www.example.com/search/brand/model/priceRange:2000-5000/year:1994-2015";
How can I identify the price range and the year? So that my final variables result in this:
$price_from = 2000;
$price_until= 5000;
$year_from = 1994;
$year_until= 2015;
After reading a few posts I've tought of using the explode() method but I'm not sure how to do it having a string like this, thanks in advance
EDIT:
I forgot to mention that the order of the elements in the URL can change, thank you
You could try something like this:
$result = array();
$url_parts = explode('/', $URL);
foreach ($url_parts as $part) {
if (strpos($part, ':') && strpos($part, '-')) {
$sub = explode(':', $part);
$range = explode('-', $sub[1]);
$result[$sub[0].'_from'] = $range[0];
$result[$sub[0].'_until'] = $range[1];
}
}
demo
I'm creating an array in PHP to send back to the front end for display in a Flot line chart. I have data that should be displayed year to date by month. If my SQL statement doesn't find any values for a given month, there is no array element for that month, and the Flot chart doesn't plot a data point for that month (See Mar and Apr in screenshot below). I'd like it to show a zero data point for months where there is no data.
Here's how I'm creating my array:
$array = array();
$array['data'] = Array();
$array['label'] = $tags[0]['tag_name'];
foreach($tags as $key=>$value) {
$month = $value['month'];
$arr = Array($month, $value['trans_amount']);
array_push($array['data'], $arr);
}
Current output:
{"data":[[1,"75.00"],[2,"170.00"],[5,"100.00"]],"label":"example label"}
Desired output:
{"data":[[1,"75.00"],[2,"170.00"],[3, "0"],[4, "0"],[5,"100.00"]],"label":"example label"}
and here's how the chart currently displays with the current output:
This works. It's a slight modification of your foreach loop. You need an extra variable $monthVal keep track of the current month.
//Assuming this the month uptil which you want the data.
$current_month = 7;
$monthVal = 1;
foreach($tags as $key=>$value) {
$month = $value['month'];
if($month != $monthVal){
while($month != $monthVal){
$array['data'][] = Array($monthVal, "0");
$monthVal += 1;
}
}
$arr = Array($month, $value['trans_amount']);
array_push($array['data'], $arr);
$monthVal += 1;
}
//This loop is added to append the array if the last entry is not equal to $current_month.
while($monthVal <= $current_month){
$array['data'][] = Array($monthVal, "0");
$monthVal += 1;
}
This should work. What I do is check if there is a missing months and then populate that month with zero as value.
$currMonth = 1;
foreach($tags as $key=>$value) {
$month = $value['month'];
if($month != $currMonth){
//if we are missing some months populate that month with zero as value
while($month != $currMonth){
array_push($array['data'],Array($currMonth, "0"));
$currMonth++;
}
}
$arr = Array($month, "'" . $value['trans_amount'] . "'");
array_push($array['data'], $arr);
$currMonth++;
}
echo json_encode($array);
I would change your SQL query to return more data, if it is stored as a date.
Try to maintain dates as dates rather than integers. PHP and SQL date functions are extensive and useful.
This simple for loop will fill the array with the missing data from the SQL query before the foreach.
for($i=1;$i<=12;$i++){
if(!isset($tags[$i])){
$tags[$i]['month'] = $i;
$tags[$i]['trans_amount'] = 0;
}
}
foreach($tags as $key=>$value) {
$month = $value['month'];
$arr = array($month, $value['trans_amount']);
array_push($array['data'], $arr);
}
Try this (works in PHP 5.3+):
$array = array();
$month_min = $month_max = 0;
foreach($tags as $value) {
$month = $value['month'];
$array[$month - 1] = array($month, $value['trans_amount']);
$month_max = $month;
if (!$month_min) $month_min = $month;
}
$months = array_values(array_map(function ($v) { return intval($v['month']); }, $tags));
$months_range = range(1, $month_max);
foreach (array_diff($months_range, $months) as $month) {
$array[$month - 1] = array($month, 0);
}
$result = array(
'data' => array_slice($array, $month - 1),
'label' => $tags[0]['tag_name'],
);
print_r(json_encode($result));