I have a big piece of php code that builds a dropdown menu and I want to minimize it by loading the select options from a text file. How to do this in the right way with php?
An example of original code:
$field['options'] = array(
array('value' => 'Anenii Noi', 'text' => 'Anenii Noi', 'depth' => 0),
array('value' => 'Bălţi', 'text' => 'Bălţi', 'depth' => 0),
array('value' => 'Basarabeasca', 'text' => 'Basarabeasca', 'depth' => 0),
....
array('value' => 'Ungheni', 'text' => 'Ungheni', 'depth' => 0)
);
And this is what I try to do, but without success:
// read a text file with select options
// where each option is a seperate line
$file_array = str_replace("\n","", file($file_path));
// build the list of arrays with select options
foreach ($file_array as $location)
$options .= "array('value' => '" . $location . "', 'text' => '" . $location . "', 'depth' => 0),";
foreach($form['field'] as $k => $field) {
// replace the big list of arrays with $options variable
$field['options'] = array($options);
$form['field'][$k] = $field;
break;
}
Looks like you had it almost. But you tried to mimic the pure php code, that might have worked if you use eval() later on, but you need to mimic its functionality.
// read a text file with select options
// where each option is a seperate line
$file_array = str_replace("\n","", file($file_path));
// build the list of arrays with select options
$options = array();
foreach ($file_array as $location) {
$options[] = array('value' => $location, 'text' => $location, 'depth' => 0);
}
foreach($form['field'] as $k => $field) {
$field['options'] = $options;
$form['field'][$k] = $field;
break;
}
Related
I want to print HTML table (30+ cols, 500+ rows) but before that I have to apply different function on almost each column values.
$sampleData = array(
0 => array(
'date' => '2015-10-20',
'time' => '12:30:00',
'price' => 500,
'currency' => 'EUR'
),
1 => array(
'date' => '2015-10-21',
'time' => '08:10:00',
'price' => 250,
'currency' => 'USD'
),
2 => array(
'date' => '2015-10-22',
'time' => '21:45:00',
'price' => 300,
'currency' => 'EUR'
)
);
So far I solved it with array of columns and names of functions that are called with call_user_func.
$cols = array(
'date' => 'self::formatDate',
'time' => 'self::formatTime'
);
And then create table like this:
$htmlRows = '';
foreach ($sampleData as $row) {
$htmlRows .= '<tr>';
foreach ($cols as $th => $function) {
$htmlRows .= '<td>'.call_user_func($cols[$th], $row[$th]).'</td>';
}
$htmlRows .= '</tr>';
}
To me it looked like quite elegant solution, but than I stuck on how to call function with two or more params, e.g. formatPrice($price, $currency); on third column while its values are stored under third and fourth key. Or is there a better way how to format table columns?
Thanks, sorry for english
Proposition:
Incorporate all fields you want to use for a specific column in a way you can split them easily, iterate over them and pass the collected values.
$cols = array(
'date' => 'self::formatDate',
'time' => 'self::formatTime',
'price,currency' => 'self::formatPrice',
);
and
$htmlRows = '';
foreach ($sampleData as $row) {
$htmlRows .= '<tr>';
foreach ($cols as $group => $function) {
$data = array();
$fields = explode(',', $group);
foreach ($fields as $field) {
$data[$field] = $row[$field];
}
$htmlRows .= '<td>'.call_user_func($cols[$th], $data).'</td>';
}
$htmlRows .= '</tr>';
}
You will have to adapt your formatXxx() functions to interpret the different representation.
It is actually a good idea to use the actual class name instead of self in the $cols array, because if you declare the functions as private and extend the class, the functions will not be found.
One way of doing it is to do another foreach and prepare a second array that is used for the HTML formatting.
foreach ($sampleData as $row) {
$newSampleData['date'] = self::formatDate($row['date']);
$newSampleData['something'] = self::formatDate($row['something'],'argument1','argument2');
... and so on
Then you use $newSampleData for your HTML code.
Well, I am here again dealing with arrays in php. I need your hand to guide me in the right direction. Suppose the following array:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
The - (hyphen) symbol only illustrates the deep level.
Well, I need to build another array (or whatever), because it should be printed as an HTML select as below:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
Looks that for each level element, it should add a space, or hyphen to determinate that it belongs to a particular parent.
EDIT
The have provide an answer provideng my final code. The html select element will display each level as string (repeating the "-" at the begging of the text instead multi-level elements.
Here's a simple recursive function to build a select dropdown given an array. Unfortunately I'm not able to test it, but let me know if it works. Usage would be as follows:
function generateDropdown($array, $level = 1)
{
if ($level == 1)
{
$menu = '<select>';
}
foreach ($array as $a)
{
if (is_array($a))
{
$menu .= generateDropdown($a, $level+1);
}
else
{
$menu .= '<option>'.str_pad('',$level,'-').$a.'</option>'."\n";
}
}
if ($level == 1)
{
$menu = '</select>';
}
return $menu;
}
OK, I got it with the help of #jmgardhn2.
The data
This is my array:
$temp = array(
array(
'name' => 'fruits',
'sons' => array(
array(
'name' => 'green',
'sons' => array(
array(
'name' => 'mango'
),
array(
'name' => 'banana',
)
)
)
)
),
array(
'name' => 'cars',
'sons' => array(
array(
'name' => 'italy',
'sons' => array(
array(
'name' => 'ferrari',
'sons' => array(
array(
'name' => 'red'
),
array(
'name' => 'black'
),
)
),
array(
'name' => 'fiat',
)
)
),
array(
'name' => 'germany',
'sons' => array(
array(
'name' => 'bmw',
)
)
),
)
)
);
Recursive function
Now, the following function will provide an array with items like [level] => [name]:
function createSelect($tree, $items, $level)
{
foreach ($tree as $key)
{
if (is_array($key))
{
$items = createSelect($key, $items, $level + 1);
}
else
{
$items[] = array('level' => $level, 'text' => $key);
}
}
return $items;
}
Calling the funcion
Now, call the function as below:
$items = createSelect($temp, array(), 0);
Output
If you iterate the final $items array it will look like:
1fruits
2green
3mango
3banana
1cars
2italy
3ferrari
4red
4black
3fiat
2germany
3bmw
I have difficult times to figure out how to manage my loop to not override variables during the process, my example script looks as it follows
$targets = array(
array(
'site_id' => 1,
'url' => array('http://example.com','http://test.com'),
'title' => "Title_1",
'int_link' => "/internal_link/",
'icon' => '/icon_2.gif',
'teaser_index' => 5),
array(
'site_id' => 2,
'url' => array('http://example2.com','http://test2.com'),
'title' => "Title_2",
'int_link' => "/internal_link/",
'icon' => '/icon_2.gif',
'teaser_index' => 5)
)
foreach($targets as $target){
$images = array();
$links = array();
$name = array();
$loop=-1;
foreach($target['url'] as $url){
$loop++;
//parsing $url;
//the insider loop has 2 iterations
if ($loop=1){
$content .="<div>".$target['title'].$url"</div>";
}
else{
$content .="<div>".$target['title'].$url"</div>";
}
}
//write $content html to database, without to override the first $content
}
Your question is not clear but i think i understand what the likely problem might be
There are so many errors in the script which you need to fix maybe your script would run the way you want it to be .
A. $content was not define .. you need to define it
B. if ($loop=1){ should be if ($loop == 1){
C. $content .="<div>".$target['title'].$url"</div>"; is missing . and it should be something like this $content .= "<div>" . $target['title'] . $url . "</div>";
D. You if condition does not make sense since you are outputting the same information
Form what i can see you want to output Title & URL you can as well just use this simple script (Just Guessing)
$targets = array(
array(
'site_id' => 1,
'url' => array('http://example.com','http://test.com'),
'title' => "Title_1",
'int_link' => "/internal_link/",
'icon' => '/icon_2.gif',
'teaser_index' => 5),
array(
'site_id' => 2,
'url' => array('http://example2.com','http://test2.com'),
'title' => "Title_2",
'int_link' => "/internal_link/",
'icon' => '/icon_2.gif',
'teaser_index' => 5)
);
foreach ( $targets as $target ) {
$content = "";
$output = "<div> %s : %s </div>";
$content .= sprintf($output, $target['title'], implode(" , ",$target['url']));
echo $content;
// write $content html to database, without to override the first $content
}
Output
Title_1 : http://example.com , http://test.com
Title_2 : http://example2.com , http://test2.com
I'm checking to make sure an array of arrays does not contain certain strings before adding any new child arrays to the parent array
I want to make sure that if an array with the same website and condition exists a new child array will not be added to the parent array.
e.g. in this example the $newArr must not be inserted in to the array $arr because their already exists an array with the same website and condition.
$arr = array(
array(
'website' => 'amazon',
'price' => 20,
'location' => 'uk',
'link' => '...',
'condition' => 'new'
),
array(
'website' => 'abe',
'price' => 20,
'location' => 'uk',
'link' => '...',
'condition' => 'new'
)
);
$newArr = array(
'website' => 'amazon',
'price' => 60,
'location' => 'uk',
'link' => '...',
'condition' => 'new'
)
I'm looking for an easy solution as using the function in_array on the parent array is not enough.
code so far
$arr = array();
foreach($table->find('tr.result') as $row){
if(($website = $row->find('a img',0))
&& ($price = $row->find('span.results-price a',0))
&& ($location = $row->find('.results-explanatory-text-Logo'))
&& ($link = $row->find('a',0))){
$website = str_replace( array('.gif','.jpg','.png'), '', basename($website->src));
$price = floatval(trim(str_replace(',', '', $price->innertext), "£"));
$location = "uk";
$link = $link->href;
$arr[] = array(
'website' => $website,
'price' => $price,
'location' => $location,
'link' => $link,
'condition' => 'new'
);
}
}
You loop over $arr each time to look for $website and $condition (always 'new'?) or you can keep a secondary array of the found keys. If you're starting with an empty $arr each time, the second approach will work and be faster.
$arr = array();
$keys = array();
foreach($table->find('tr.result') as $row){
if(...){
...
$condition = 'new'; // set as needed
// track seen keys
$key = $website . '|' . $condition; // assumes neither field contains '|'
if (!isset($keys[$key])) {
$keys[$key] = true;
$arr[] = array(...);
}
}
}
I hope the comments in the below code speak for themselves... I'm not a PHP pro, and this is probably not the most elegant way, but I believe the logic makes sense. Obviously the $new_array object has some variables that aren't declared but it's for example only.
I hope that helps and that no one down votes me :)
<?php
// Original array
$arr = array();
foreach($result as $row) {
// Get the new array as an object first so we can check whether to add to the loop
$new_array = array(
'website' => $website,
'price' => $price,
'location' => $location,
'link' => $link,
'condition' => 'new'
);
// If the original array is empty there's no point in looping through it
if(!empty($arr)) {
foreach($arr as $child) {
// Check through each item of the original array
foreach($new_array as $compare) {
// Compare each item in the new array against the original array
if(in_array($compare, $child)) {
// if there's a match, the new array will not get added
continue;
}
}
}
}
// If there's no match, the new array gets added
$arr[] = $new_array;
}
?>
I have an array in this form:
$data = array(
array(
'id' => '1',
'bar' => 'foo',
'page' => 'front',
),
array(
'id' => 'bar',
'bar' => 'foo',
'page' => 'front',
),
array(
'id' => 'different,
'bar' => 'bar',
'page' => 'back',
),
array(
'id' => 'another',
'title' => __("Custom CSS",'solidstyle_admin'),
'foo' => 'bar',
'page' => 'back',
),
);
And I want to list all ids grouped by pages and saved as variables, so if the above array is an input then output will look just like this one:
$front = array('1','bar');
$back = array('different','another');
//$data['page'] = array($id1, $id2, (...));
I was trying to do that using foreach and this is how it starts:
function my_output() {
foreach($data as $something) {
$id = $something['id'];
$page = $something['page'];
}
return $output;
}
I was trying multiple foreach loops, and the best result I got was:
front = 1
front = bar
back = different
back = another
But I have absolutely no idea how to achieve what I want to do, I don't want anyone to do my job, just any hints? Keep in mind I'm a bit new to PHP and I don't know too much about arrays.
Thank you!
Sounds like you want:
$ids = array();
foreach ($data as $page) {
$pageName = $page['page'];
// create an empty array for your IDs
if (!isset($ids[$pageName])) {
$ids[$pageName] = array();
}
// add to the array of IDs
$ids[$pageName][] = $page['id'];
}
var_dump($ids); // array('front' => array('1', 'bar'), ...
Stick with the loop idea and do a conditional check.
function my_output() {
$front = array();
$back = array();
foreach($data as $something) {
$id = $something['id'];
$page = $something['page'];
if ($page === 'front') {
$front[] = $id;
} else if ($page === 'back') {
$back[] = $id;
}
}
// Not sure what you want to return here, but you could return an array of pages
$output = array('front' => $front, 'back' => $back);
return $output;
}
This will return something similar to:
$output = array(
'front' => array(
0 => '1',
1 => 'bar',
),
'back' => array(
0 => 'something',
1 => 'another',
)
)
Edit: Keep in mind that my answer only accounts for the two pages you listed in your answer. If you have more pages you can also use what cbuckley's answer showed.