0

Trying to end up with 7 arrays ($mon, $tue, $wed, $thu, $fri, $sat, $sun) that contain a value of either 0 or 1 for each hour of the day given initial array $hours. $hours is just a posted array that contains user selected hours for each day of the week.

I believe the problem is my use of variable variables ($$day) as my weekday arrays all return null ($mon, $tue, $wed, $thu, $fri, $sat, $sun). Any assistance would be appreciated.

$hours =

Array
(
    [mon] => Array
        (
            [0] => 12pm
            [1] => 1pm
            [2] => 2pm
            [3] => 3pm
            [4] => 4pm
            [5] => 5pm
            [6] => 6pm
            [7] => 7pm
        )

    [tue] => Array
        (
            [0] => 12am
            [1] => 1am
            [2] => 2am
            [3] => 3am
            [4] => 4am
            [5] => 5am
            [6] => 6am
            [7] => 7am
            [8] => 8am
            [9] => 9am
            [10] => 10am
            [11] => 11am
            [12] => 12pm
            [13] => 1pm
            [14] => 2pm
            [15] => 3pm
            [16] => 4pm
            [17] => 5pm
            [18] => 6pm
            [19] => 7pm
            [20] => 8pm
            [21] => 10pm
            [22] => 11pm
        )

    [sun] => Array
        (
            [0] => 12am
        )

)

the code :

//create an array of weekdays
$weekdays = array('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun');

foreach($weekdays as $day)
{

    //set hours for each day using variable variables $$day = mon, tue, wed, etc
    if($hours[$day])
    {
        $$day['12a'] = in_array("12am", $hours[$day]) == 1 ? 1 : 0;
        $$day['1a'] = in_array("1am", $hours[$day]) == 1 ? 1 : 0;
        $$day['2a'] = in_array("2am", $hours[$day]) == 1 ? 1 : 0;
        $$day['3a'] = in_array("3am", $hours[$day]) == 1 ? 1 : 0;
        $$day['4a'] = in_array("4am", $hours[$day]) == 1 ? 1 : 0;
        $$day['5a'] = in_array("5am", $hours[$day]) == 1 ? 1 : 0;
        $$day['6a'] = in_array("6am", $hours[$day]) == 1 ? 1 : 0;
        $$day['7a'] = in_array("7am", $hours[$day]) == 1 ? 1 : 0;
        $$day['8a'] = in_array("8am", $hours[$day]) == 1 ? 1 : 0;
        $$day['9a'] = in_array("9am", $hours[$day]) == 1 ? 1 : 0;
        $$day['10a'] = in_array("10am", $hours[$day]) == 1 ? 1 : 0;
        $$day['11a'] = in_array("11am", $hours[$day]) == 1 ? 1 : 0;
        $$day['12p'] = in_array("12pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['1p'] = in_array("1pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['2p'] = in_array("2pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['3p'] = in_array("3pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['4p'] = in_array("4pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['5p'] = in_array("5pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['6p'] = in_array("6pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['7p'] = in_array("7pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['8p'] = in_array("8pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['9p'] = in_array("9pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['10p'] = in_array("10pm", $hours[$day]) == 1 ? 1 : 0;
        $$day['11p'] = in_array("11pm", $hours[$day]) == 1 ? 1 : 0;
    }

}

//debugging only to see variable values
file_put_contents('/home/test/public_html/file.txt', print_r($hours, true));
file_put_contents('/home/test/public_html/file-mon.txt', print_r($mon, true));
file_put_contents('/home/test/public_html/file-tue.txt', print_r($tue, true));
file_put_contents('/home/test/public_html/file-wed.txt', print_r($wed, true));
file_put_contents('/home/test/public_html/file-thu.txt', print_r($thu, true));
file_put_contents('/home/test/public_html/file-fri.txt', print_r($fri, true));
file_put_contents('/home/test/public_html/file-sat.txt', print_r($sat, true));
file_put_contents('/home/test/public_html/file-sun.txt', print_r($sun, true));

EDIT - ending solution used :

With a few changes as necessary for other aspects of my script.

//decode the json array posted
$hours = json_decode($_POST['hours'], true);

//set array of weekdays
$weekdays = array(1 => 'mon', 2 => 'tue', 3 => 'wed', 4 => 'thu', 5 => 'fri', 6 => 'sat', 7 => 'sun');

//set array of hour values
$hourDefs = array('12am', '1am', '2am', '3am', '4am', '5am', '6am', '7am', '8am', '9am', '10am', '11am', '12pm', '1pm', '2pm', '3pm', '4pm', '5pm', '6pm', '7pm', '8pm', '9pm', '10pm', '11pm');

//set result output array
$output = array();

foreach($weekdays as $day=>$day_value)
{   
    //set hours for each day using variable variables ${$day} = mon, tue, wed, etc
    if(isset($hours[$day_value]))
    {
        foreach($hourDefs as $def)
        {
            $output[$day_value][$def] = in_array($def, $hours[$day_value]) == 1 ? 1 : 0;
        }
    }           
}
user756659
  • 3,372
  • 13
  • 55
  • 110
  • 2
    `${$day}[...]` instead of `$$day[..]`, because PHP cannot determine if you want the name of the variable to be `$day` or `$day[..]` – nice ass Mar 22 '14 at 15:49
  • 1
    "I believe the problem is my use of variable variables" - well, use of variable variables is always a problem, in my opinion. Why do you not use an associative array instead, just like you have for `$hours`? – IMSoP Mar 22 '14 at 15:53
  • @onetrickpony - perfect... that is working as expected and makes sense now that I see it. – user756659 Mar 22 '14 at 15:55
  • Other things to improve your readability: [`in_array()` returns boolean](http://php.net/in_array) so you don't need that `== 1`; the 24 incredibly similar lines of code should be turned into a loop, as should the last seven calls to `file_put_contents` (easy if you have an associative array: you can just use `foreach`); if you have control of the data format, use the 24-hour clock rather than all those slightly incompatible hour labels. Oh, and `print_r` is not a good format for saving, because it isn't designed to be read back as data; try `var_export` or `serialize`, or perhaps `json_encode` – IMSoP Mar 22 '14 at 15:59
  • @IMSoP - What were you thinking? $hours could be empty or only contain values for a few days or all of course. Every way I can think of would still require a way to know the actual day. – user756659 Mar 22 '14 at 16:01
  • Those lines were only for debugging... they are not part of the actual script. The hour lables are required as that is how they are named in my db and cannot be changed without major editing in other aspects. I will probably make a loop though for the 24 hours just haven't done so at this point. – user756659 Mar 22 '14 at 16:03
  • @user756659 It's really very simple: instead of `$$day`, you write `$output[$day]`. Then you end up with a nice array with the keys being `'mon'`, `'tue'`, etc, and don't have any of the limitations and confusions that arise from dynamic variable names. – IMSoP Mar 22 '14 at 16:12

1 Answers1

1

I would restructure that code like this:

// keys; you can also use a for() loop to generate them
$hourDefs = array('12am', '1am', '2am' ... );  
$output = array();

foreach($weekdays as $day){
  if(!isset($hours[$day]))
    continue;

  // store the output inside an array so you can loop it later
  foreach($hourDefs as $def)
    $output[$day][$def] = in_array($def, $hours[$day]) == 1 ? 1 : 0;

}

foreach($output as $name => $data){
  $pathName = sprintf('/home/test/public_html/file-%s.txt', $name);
  file_put_contents($pathName, print_r($data, true));
}

If you want to keep the inconsistency between key names use substr($def, 0, -1) on $output

nice ass
  • 16,471
  • 7
  • 50
  • 89
  • This is pretty neat, but I have a couple of nit-picks: I think that `continue` will eliminate data the OP wanted, but I could be wrong. Skipping the `{}` for the innermost `foreach` like that is generally considered bad coding style, as it's incredibly easy to introduce a bug by adding a line just below and not realising it's not in the loop. – IMSoP Mar 22 '14 at 16:40