I have array of array, where i want to change date format. I am trying to get it as below
foreach ($toReturn as $value) {
$start_date = new DateTime($value['start_date']);
$value['start_date'] = $start_date->format('m-d-Y');
$end_date = new DateTime($value['end_date']);
$value['end_date'] = $end_date->format('m-d-Y');
}
here format gets changed but it is not replacing array value with new one?? Why??
If your want to change the value in the foreach, you need to access it by reference.
change foreach ($toReturn as $value) to foreach ($toReturn as &$value)
You have to change value by reference:
foreach ($toReturn as &$value) {
$start_date = new DateTime($value['start_date']);
$value['start_date'] = $start_date->format('m-d-Y');
$end_date = new DateTime($value['end_date']);
$value['end_date'] = $end_date->format('m-d-Y');
}
You should use the refrence operator & to change in the original array otherwise PHP treats it as local aary which is diffrent from the original one and the changes in that local array will not reflects to original array.
foreach ($toReturn as &$value) {
$start_date = new DateTime($value['start_date']);
$value['start_date'] = $start_date->format('m-d-Y');
$end_date = new DateTime($value['end_date']);
$value['end_date'] = $end_date->format('m-d-Y');
}
Alternately, if you do not wish to use the "Pass by reference" method, you can use this, or even create new variable.
foreach ($toReturn as $key => $value) {
$start_date = new DateTime($value['start_date']);
$toReturn[$key]['start_date'] = $start_date->format('m-d-Y');
$end_date = new DateTime($value['end_date']);
$toReturn[$key]['end_date'] = $end_date->format('m-d-Y');
}
Note: If you wish to use pass by reference, do not forget to unset($value) after the loop which is not necessary for given example.
You can also use access $toReturn[$index]
foreach ($toReturn as $index => $value) {
$start_date = new DateTime($value['start_date']);
$toReturn[$index]['start_date'] = $start_date->format('m-d-Y');
$end_date = new DateTime($value['end_date']);
$toReturn[$index]['end_date'] = $end_date->format('m-d-Y');
}
Related
I'm trying to remove stdClass property by reference. Because I don't know how deeply the property is nested, a reference is made in the loop. But the unset method does not remove variables by reference. How can I resolve it without just setting a null value?
<?php
$data = new stdClass();
$data->foo = new stdClass();
$data->foo->bar = 'value';
$pathToRemove = 'foo.bar';
$dataReference = &$data;
foreach (explode('.', $pathToRemove) as $field) {
$dataReference = &$dataReference->$field;
}
unset($dataReference);
var_dump($data);
Loop over all the elements except the last. Then use the last element as the field to delete.
$pathArray = explode('.', $pathToRemove);
$lastField = array_pop($pathArray);
$dataReference = &$data;
foreach ($pathArray as $field) {
$dataReference = &$dataReference->{$field};
}
unset($dataReference->{$lastField});
unset($dataReference); // don't need the reference variable any more
I am trying to save sets of data, through these models.
Model 1: Service
Generates a series of service dates.
Model 2: Response
For each service entry, user is required to add a set number of responses.
So, I'd like to save multiple service entries for multiple response. The code is fairly self explanatory, but I can add more information if required. I can't find an easy solution to do this, though I feel it's fairly straight forward.
if (isset($_POST['Service'], $_POST['Response']))
{
$model->attributes = $_POST['Service'];
$valid = $model->validate();
// date manipulation
$start = new DateTime($model->date_booked);
$start->format('Y-m-d');
$end = new DateTime($model->end_date);
$end->format('Y-m-d');
$interval = DateInterval::createFromDateString($model->interval);
$range = new DatePeriod($start, $interval, $end);
if ($valid)
{
foreach ($range as $key => $value)
{
$schedule = new Service;
$schedule->attributes = $_POST['Service'];
$schedule->date_booked = $value->format('Y-m-d');
// If I were to save here, the following, Response Model
// will not be validated!
// $schedule->save();
foreach ($_POST['Response'] as $j => $k)
{
$response[$j] = new Response;
$response[$j]->attributes = $_POST['Response'][$j];
// If I were to save the Service Models here,
// evidently, entries are doubled up!
// $service->save();
$response[$j]->service_id = $service->id;
$valid = $response[$j]->validate() && $valid;
// $response[$j]->save();
}
}
}
}
Thank you!
I had to just run through, yet another foreach loop, to get this working. Yes, I do feel like I am iterating the loops, so if someone have another elegant solution, by all means share them to me. :-)
For now, this is done.
if (isset($_POST['Service'], $_POST['Response']))
{
// Assign and validate Service mcrypt_module_is_block_algorithm
$model->attributes = $_POST['Service'];
$valid = $model->validate();
// date manipulation
$start = new DateTime($model->date_booked);
$start->format('Y-m-d');
$end = new DateTime($model->end_date);
$end->format('Y-m-d');
$interval = DateInterval::createFromDateString($model->interval);
$range = new DatePeriod($start, $interval, $end);
// Assign and Validate Response Populated questions
foreach ($_POST['Response'] as $j => $k)
{
$response[$j] = new Response('populate'); // populate scenario
$response[$j]->attributes = $_POST['Response'][$j];
$valid = $response[$j]->validate() && $valid;
}
if ($valid)
{
foreach ($range as $key => $value)
{
$schedule = new Service; // static model
$schedule->attributes = $_POST['Service'];
$schedule->date_booked = $value->format('Y-m-d');
$schedule->save();
foreach ($_POST['Response'] as $x => $y)
{
$response[$x] = new Response('populate'); // populate scenario
$response[$x]->attributes = $_POST['Response'][$x];
$response[$x]->service_id = $schedule->id;
$response[$x]->save();
}
}
}
}
I need to combine two different data types, an array and an array object.
I then need to display them on a page in order of a certain attribute (date).
The markup for access is similar to the following:
foreach($array as $item){
$item['date'];
}
and
foreach($object as $item){
$item->post->date
}
is array_merge what I need, or something different?
Not that if possible I'd like to do this on the fly, as data will be changing rapidly and there is no need for storage.
Thanks!
Here's how I would do it:
// array we will use for sorting
$finalArray = array();
// add the array's using the date as the key
foreach($array as $item){
$key = $item['date']; // use date here, example $key = date('l \t\h\e jS',$item['date']);
$finalArray[$key] = $item;
}
// add the objects's using the date as the key
foreach($object as $item){
$finalArray[$item->post->date] = $item;
}
//now sort by keys as Xeoncross noted
ksort($finalArray);
foreach($finalArray as $date=>$objOrArray){
if(is_array($objOrArray)){
//do your array printing here
} else {
//do your object printing here
}
}
Ofcourse we can turn the object into an array with get_object_vars, and use whatever sorting function on the final array, the important part is that we want to sort by date and that's why we need it to be our key.
Hope that helped.
foreach($array as $item){
$array_new[] = $item['date'];
}
foreach($object as $item){
$array_new[] = $item->post->date;
}
sort($array_new);
$dates = array();
foreach ($array as $item) {
$dates[] = $item['date'];
}
foreach ($object as $item) {
$dates[] = $item->post->date;
}
sort($dates);
foreach ($dates as $date) {
echo $date;
}
You could try this if you need multiple values from the objects (not just date) and you don't mind duplicates being erased.
// $array is already defined right?
$object = json_decode(json_encode($object), TRUE);
$data = array_merge($array, $object);
print_r($data); // now test it
http://us2.php.net/array_merge
http://us3.php.net/json_decode (note the second TRUE param)
Edit
Based on Perfection's answer, (and re-reading the question) I would do this:
$finalArray = array();
foreach($array as $item)
{
$finalArray[$item['date']] = $item;
}
foreach($object as $item)
{
$finalArray[$item->post->date] = json_decode(json_encode($item), TRUE);
}
ksort($finalArray);
foreach($finalArray as $date => $item)
{
// Everything is an array now
}
I am looking to store some objects in an array during a foreach loop. The problem is creating a unique object each time. I have to have some kind of index appending the name of each object. Here is what I have:
function table_rows($html) {
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
($check_object . $key) = new check_class;
($check_object . $key)->check_method1($table_row);
($check_object . $key)->check_method2($table_row);
($check_object . $key)->check_method3($table_row);
$check_array[] = (check_object . $key);
}
}
Am I even close?
You could use variables for that:
function table_rows($html) {
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
$object = new check_class;
$object->check_method1($table_row);
$object->check_method2($table_row);
$object->check_method3($table_row);
$check_array[] = $object;
}
}
Of course naming the variable for an object instance $object is not very descriptive, but I hope you get the idea.
This works because the first assignment in the for-loop overwrites the "old" instance, so $object unique for each iteration.
In case Jared Drake is right and what you mean is unique array keys, not object (variable) names.
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
$check_object = new check_class;
$check_object->check_method1($table_row);
$check_object->check_method2($table_row);
$check_object->check_method3($table_row);
$check_array['check_object' . $key] = $check_object;
}
}
Maybe I'm misunderstanding the question, but can't you just use the array_push method to add each object to the end of the array in your foreach loop?
I am writing a PHP script where the inputs are:
From date
To date
I then want to take that date range and create an array of some sort that has:
Array(date,x)
As I add each date to the array, I will calculate the value that goes with it.
With .NET I would (off the top of my head) use a dictionary where the date was the key and x is the value.
The main task is getting that date range, then splitting that range into an array or dictionary of some sort (What would be ideal in php)
As i'm adding it to the array i'll run off some other code i've already wrote that calculate the value to go with that date
At the end of it all when it's added in there, i'll need to iterate through the array or list and add all the x values together.
(Untested)
function dateArray($from, $to, $value = NULL) {
$begin = new DateTime($from);
$end = new DateTime($to);
$interval = DateInterval::createFromDateString('1 day');
$days = new DatePeriod($begin, $interval, $end);
$baseArray = array();
foreach ($days as $day) {
$dateKey = $day->format("Y-m-d");
$baseArray[$dateKey] = $value;
}
return $baseArray;
}
$datesArray = dateArray('2011-01-01', '2011-03-31',true);
you can try this
function makeDateRange($from,$to,$pattern='m-d-y')
{
$day = date( $pattern , $from );
$to = date( $pattern , $to );
$parseDate = date_parse($from);
while( $day <= $to ) {
$day = mktime(0,0,0,$parseDate["month"],$parseDate["day"]+1,$parseDate["year"]);
$dateArray[] = date($pattern , $day);
}
return $dateArray;
}
// here make array
$keys = makeDateRange("12-01-11","12-02-11");
//here make above array as key in $a array
$a = array_fill_keys($keys, 'none');
print_r($a);
If I understand you correctly, you could use an associative array for that:
array(
'00-00-00' => $value,
'01-01-01' => $value,
// etc...
);
Or you can create it like this:
$myArray = array();
$myArray['00-00-00'] = $value;
$myArray['01-01-01'] = $value;
You could populate them by running a loop...