Creating menu from Text - php

I am very new to PHP programming and dont know the exact syntax of various labrary functions like , split, find ,etc.
I am having following text with me
in a string variable
$menu = '/home-page|HOME
/our-iphone-app|OUR iPhone APP
/join-us|JOIN ME
/contact-us|CONTACT US';
I want to populate to arrays with this text one array containing the portion before the pipe | and second array contains portions after pipe. How to do this using some split by char(|) method.
Finally arrays must contain
$arraypage = {'0'->'/home-page','1'->'/our-iphone-app'} // etc, and...
$arrayTitle = {'0'->'HOME','2'->'OUR iPhone App'} // etc

You need to break up the string by new lines and then by pipe characters.
$lines = explode("\n", $menu);
$arraypage = array();
$arrayTitle = array();
foreach($lines as $line) {
list($arraypage[], $arrayTitle[]) = explode('|', $line);
}
var_dump of the resulting arrays gives:
array
0 => string '/home-page' (length=10)
1 => string '/our-iphone-app' (length=15)
2 => string '/join-us' (length=8)
3 => string '/contact-us' (length=11)
array
0 => string 'HOME' (length=4)
1 => string 'OUR iPhone APP' (length=14)
2 => string 'JOIN ME' (length=7)
3 => string 'CONTACT US' (length=10)

$array = explode("\n", $array);
$result1 = array();
$resutl2 = array();
foreach($array as $arr){
$temp = explode('|', $arr);
$result1[] = $temp[0];
$result2[] = $temp[1];
}

I'd suggest you make your string contain another separator like so:
$menu = '/home-page|HOME:/our-iphone-app|OUR iPhone APP:/join-us|JOIN ME:/contact-us|CONTACT US';
Then you can use the explode method to split up your string to an associative array.
$array = explode(":", $menu);
foreach($array as $key => $val) {
$array[$key] = explode("|", $val);
}

I'd probably just define the data in an array to start with, rather than as a string. I'd also build it in the format
$menu_array = {
{'url'=>'/home-page','text'=>'HOME'},
{'url'=>'/our-iphone-app','text'=>'OUR iPhone APP'},
{'url'=>'/join-us','text'=>'JOIN ME'},
{'url'=>'/contact-us','text'=>'CONTACT US'},
};
Since that's almost certainly going to be more useful for whatever you do with it next.
If you do need to use a string for some reason though, I'd say a regular expression is the tidiest way to do this. The following:
preg_match_all('/^(?P<url>[^|]+)\\|(?P<text>\\V+)\\v*$/m',$menu,$menu_array,PREG_SET_ORDER)
would set $menu_array to the format I used above.
In fairness, using a regular expression for this may be a little overkill, but I prefer the power of regexes, which are easier to tweak later when you want to add things than loops of explode()s.

Related

Creating mulitdimensional array from csv list

I think this is a beginner's question..
I cannot find an example of this, although that may reflect that I am too naive to know what to search for..
If I have a string (the comma could be any other character):
58732,hc_p0d
58737,hc_p4
58742,hc_p4a
(new lines use "\r\n")
How can I split this into a multidimensional array (2X3 in this case, but the number of rows can vary.)
I think is the form I would want (But please suggest better ways if this is not appropriate!):
array(
array(58732,hc_p0d),
array(58737,hc_p4),
array(58742,hc_p4a),
)
The nearest I have got is using $vars = explode("\r\n",$input);
With vars looking like this (in cakephp):
(int) 0 => '58732,hc_p0d',
(int) 1 => '58737,hc_p4',
(int) 2 => '58742,hc_p4a',
(int) 3 => '58747,hc_p4b',
Thanks
If you want to convert CSV data to array format you can do it in this way
$csv = array_map('str_getcsv', file('data.csv'));
Check this reference for further explanation
http://php.net/manual/en/function.str-getcsv.php
And if it is not from file but a string containing CSV data you can do it like
$data = $csv_data;
$csv_data_rows = explode('\r\n',$data);
$final_array = array();
foreach($csv_data_rows as $key => $value){
$final_array[$key] = explode(',',$value);
}
return $final_array;

Manipulate massive array of strings

From one of our vendors I received a DVD with 12K+ images. Before i put them on our webserver, I need to resize, rename and copy them.
To do this I'm writing a PHP cli program.
And it seems that I am a little stuck with it...
All the files fit a certain pattern.
The copy and rename are not the problem, the manipulation of the strings is.
So to symplify the example code: lets suppose that I have an array with strings and I want to put them into a new array.
The original array looks like this:
$names = array (
'FIX1_VARA_000.1111_FIX2',
'FIX1_VARB_000.1111.2_FIX2',
'FIX1_VARB_222.2582_FIX2',
'FIX1_VARC_555.8794_FIX2',
'FIX1_VARD_111.0X00(2-5)_FIX2',
'FIX1_VARA_112.01XX(09-13)_FIX2',
'FIX1_VARB_444.XXX1(203-207).2_FIX2'
);
Each string in this array starts with the same fixed part in the front and ends with the same fixed part in the end FIX1 & FIX2 respectively.
After FIX1 there always is an underscore followed by a variable part, followed by an underscore. I'm not interested in the fixed parts or the variable parts. So I cut it all away.
The remaining string can be of the following two types:
If it only contains numbers and points: then it is a valid string and I put it
in the $clean array. EG: 000.1111 or 000.111.2
If the string does not only have numbers and points in it, then it always has several X's in it and a an open an closed bracked with numbers and a -.
Like 444.XXX1(203-207).2
The numbers between the brackets form a series, and each number in this series needs to replace the X's. The strings that should be put in the $clean array are:
444.2031.2
444.2041.2
444.2051.2
444.2061.2
444.2071.2
This is the part I'm struggling with.
$clean = array();
foreach ($names as $name){
$item = trim(strstr(str_replace(array('FIX1_', '_FIX2'),'',$name), '_'),'_');
// $item get the values:
/*
* 000.1111,
* 000.1111.2,
* 222.2582,
* 555.8794,
* 111.0X00(2-5),
* 112.01XX(09-13),
* 444.XXX1(203-207).2
*
*/
// IF an item has no X in it, it can be put in the $clean array
if (strpos($item,'X') === false){
//this is true for the first 4 array values in the example
$clean[] = $item;
}
else {
//this is for the last 3 array values in the example
$b = strpos($item,'(');
$e = strpos($item,')');
$sequence = substr($item,$b,$e-$b+1);
$item = str_replace($sequence,'',$item);
/* This is the part were I'm stuck */
/* ------------------------------- */
/* it should get the values in the sequence variable and iterate over them:
*
* So for $names[5] ('FIX1_VARA_112.01XX(09-13)_FIX2') I want the folowing values entered into the $clean array:
* Value of $sequence = '(09-13)'
*
* 112.0109
* 112.0110
* 112.0111
* 112.0112
* 112.0113
*
*/
}
}
//NOW ECHO ALL VALUES IN $clean:
foreach ($clean as $c){
echo $c . "\n";
}
The final output should be:
000.1111
000.1111.2
222.2582
555.8794
111.0200
111.0300
111.0400
111.0500
112.0109
112.0110
112.0111
112.0112
112.0113
444.2031.2
444.2041.2
444.2051.2
444.2061.2
444.2071.2
Any help with the "Here I'm stuck" part would be greatly appreciated.
Like #stdob-- mentioned, regular expressions really are what you want. Here's a working version of the code:
$names = array (
'FIX1_VARA_000.1111_FIX2',
'FIX1_VARB_000.1111.2_FIX2',
'FIX1_VARB_222.2582_FIX2',
'FIX1_VARC_555.8794_FIX2',
'FIX1_VARD_111.0X00(2-5)_FIX2',
'FIX1_VARA_112.01XX(09-13)_FIX2',
'FIX1_VARB_444.XXX1(203-207).2_FIX2'
);
$clean = array();
foreach ($names as $name){
$item = trim(strstr(str_replace(array('FIX1_', '_FIX2'),'',$name), '_'),'_');
// $item get the values:
/*
* 000.1111,
* 000.1111.2,
* 222.2582,
* 555.8794,
* 111.0X00(2-5),
* 112.01XX(09-13),
* 444.XXX1(203-207).2
*
*/
// IF an item has no X in it, it can be put in the $clean array
if (strpos($item,'X') === false){
//this is true for the first 4 array values in the example
$clean[] = $item;
}
else {
// Initialize the empty matches array (I prefer [] to array(), but pick your poison)
$matches = [];
// Check out: https://www.regex101.com/r/qG4jS4/1 to see visually how this works (also, regex101.com is just rad)
// This uses capture groups, which get stored in the $matches array.
preg_match('/\((\d*)-(\d*)\)/', $item, $matches);
// Now we've got the array of values that we want to have in our clean array
$range = range($matches[1], $matches[2]);
// Since preg_match has our parenthesis and digits grabbed for us, get rid of those from the string
$item = str_replace($matches[0],'',$item);
// Truly regrettable variable names, but you get the idea!
foreach($range as $number){
// Here's where it gets ugly. You're wanting the numbers to work like strings (have consistent length
// like 09 and 13) but also work like numbers (when you create a sequence of numbers). That kind of
// thinking begets hackery. This probably isn't your fault, but it seems helpful to point out.
// Anyways, we can use the number of X's in the string to figure out how many characters we ought
// to be adding. This is important because otherwise we'll end up with 112.019 instead of 112.0109.
// PHP casts that '09' to (int) 9 when we run the range() function, so we lose the leading zero.
$xCount = substr_count($item, 'X');
if($xCount > strlen($number)){
// This function adds a given number ($xCount, in our case) of a character ('0') to
// the end of a string (unless it's given the STR_PAD_LEFT flag, in which case it adds
// the padding to the left side)
$number = str_pad($number, $xCount, '0', STR_PAD_LEFT);
}
// With a quick cheat by padding an empty string with the same number of X's we counted earlier...
$xString = str_pad('', $xCount, 'X');
// Now we can add the fixed string into the clean array.
$clean[] = str_replace($xString, $number, $item);
}
}
}
// I also happen to prefer var_dump to echo, but again, your mileage may vary.
var_dump($clean);
It outputs:
array (size=18)
0 => string '000.1111' (length=8)
1 => string '000.1111.2' (length=10)
2 => string '222.2582' (length=8)
3 => string '555.8794' (length=8)
4 => string '111.0200' (length=8)
5 => string '111.0300' (length=8)
6 => string '111.0400' (length=8)
7 => string '111.0500' (length=8)
8 => string '112.0109' (length=8)
9 => string '112.0110' (length=8)
10 => string '112.0111' (length=8)
11 => string '112.0112' (length=8)
12 => string '112.0113' (length=8)
13 => string '444.2031.2' (length=10)
14 => string '444.2041.2' (length=10)
15 => string '444.2051.2' (length=10)
16 => string '444.2061.2' (length=10)
17 => string '444.2071.2' (length=10)
--Edit-- Removed my warning about strpos and ==, looks like somebody already pointed that out in the comments.
First, I'll suppose all your files have valid patterns, so no file has something wrong in it, otherwise, just add security conditions...
in $sequence, you get the (09-13).
To use digits, you have to remove ( and ), so make an other variable :
$range = substr($item,$b,$e-$b+1);
// you get '09-13'
then you need to split it :
list($min, $max) = explode("-",$range);
// $min = '09', $max = '13'
$nbDigits = strlen($max);
// $nbDigits = 2
Then you need all digits from min to max :
$numbersList = array();
$min = (int)$min; // $min becomes 9, instead of '09'
$max = (int)$max;
for($i=(int)$min; $i<=(int)$max; $i++) {
// set a number, including leading zeros
$numbersList[] = str_pad($i, $nbDigits, '0', STR_PAD_LEFT);
}
Then you have to generate file names with those digits :
$xPlace = strpos($item,'X');
foreach($numbersList as $number) {
$filename = $item;
for($i=0; $i<$nbDigits; $i++) {
// replacing one digit at a time, to replace each 'X'
$filename[$xPlace+$i] = $number[$i];
}
$clean[] = $filename;
}
It should do some work, there may be some errors, but it is a good start, give it a try :)

Grouping in PHP using a character

I have an array like:
array{
0 => string 'B.E - ECE',
1 => string 'B.E - EEE',
2 => string 'Msc - Maths',
3 => string 'Msc - Social',
}
So how can I make the array into groups like:
B.E. => ECE, EEE
Msc => Maths,Social
?
I want to do it in PHP. Can anybody help me how to achieve it ?
So is your array split by the "-" character?
so it's Key - Value pairs split by commas?
Ok -
(edit: section removed to clarify answer)
Following conversation and some rearrangement of the question, a second try at a solution, with the above assumptions, try this:
$array = array {
0 => string 'B.E - ECE' (length=9)
1 => string 'B.E - EEE' (length=9)
2 => string 'Msc - Maths' (length=11)
3 => string 'Msc - Social' (length=12)
}
foreach ($array as $row){
$piece = explode("-",$row);
$key = $piece[0];
$newArray[$key][] = $piece[1];
unset($piece);
}
unset($row) ///tidy up
This will output two arrays each of two arrays:
$newArray[Msc] = array("Maths","Social");
$newArray[B.E] = array("ECE","EEE");
What I did was cause the Foreach loop to automatically add onto the array if the key exists with $newArray[$key][] so that the values are automatically collected by key, and the key is defined as the first half of the original array values.
Printing:
To print the result:
foreach($newArray as $key=>$newRow){
/// there are two rows in this case, [B.E] and [MSc]
print $key.":<br>";
print "<pre>";
///<pre> HTML tag makes output use linebreaks and spaces. neater.
print_r($newRow);
///alternatively use var_dump($newRow);
print "</pre>";
}
Alternatively if you wish to print a known named variable you can write:
print_r($newArray['B.E']);
Which will print all the data in that array. print_r is very useful.
what you want is php's explode. Not sure if this will give you the perfect answer but should give you an idea of what to do next.
$groupedArray = array();
foreach($array as $row){
$split = explode(" - ",$row);
$groupedArray[] = $split[0];
}
array_unique($groupedArray); //This will give you the two groupings
foreach($array as $row){
$split = explode(" - ",$row);
$pos = array_search($split[0],$groupedArray);
if($pos !== FALSE){
$groupedArray[$pos][] = $split[1];
}
}
This should give you a full formatted array called $groupedArray where $array is the array you already have.
Hope this helps!

merging two elements of two arrays in php

Hello Everyone I have a Array in php like
array (size=2)
0 => string 'A6,A5,B12,B11,' (length=14)
1 => string 'B6,B5,B8,B7,' (length=12)
on var_dump($arr). How could I convert it to something like
array('A6,A5,B12,B11,B6,B5,B8,B7,')
in php.
here is what i'm doing eaxctly to get the above array
$id= "1";
$data['busInfo']= $this->dashboard_model->find_bus($id);
$data['reservationInfo'] = $this->dashboard_model->get_booked_seats_info($id);
$arr =array();
foreach ($data['reservationInfo'] as $reserved){
$seatBooked = $reserved->seats_numbers;
array_push($arr, $seatBooked);
}
var_dump($arr);
I'm using Codeigniter as my framework.
You can just append to a string, then create a single element array with that string (if you actually need an array):
$data['reservationInfo'] = $this->dashboard_model->get_booked_seats_info($id);
$str='';
foreach ($data['reservationInfo'] as $reserved){
$str .= $reserved->seats_numbers;
}
var_dump(array($str));
Or just implode the source array:
var_dump(array(implode('', $this->dashboard_model->get_booked_seats_info($id))));

php define variable inside str_replace array

I have a template system, that replaces text such as {HEADER} with the appropriate content. I use an array like this, that replaces the key with the value using str_replace.
$array = array("HEADER","This is the header");
foreach($array as $var => $content) {
$template = str_replace("{" . strtoupper($var). "}", $content,$template);
}
Now im trying to use a defined variable like this:
define("NAME","Site Name");
Inside the value for the header. So I want the defined variable to be inside the array which gets replaced so it would look like this, but it doesn't work.
$array = array("HEADER","Welcome to ".NAME."'s website!");
Any ideas? tell me if im not clear
Shouldn't your array line be:
$array = array("HEADER" => "Welcome to ".NAME."'s website!");
Since you are accessing the array items by key and value?
The way you are looping through the array, using :
foreach($array as $var => $content) {
// ...
}
makes me think you should use an associative array for your $array.
i.e., it should be declared this way :
$array = array("HEADER" => "Welcome to ".NAME."'s website!");
And, as a demonstration, here's an example of code :
$template = <<<TPL
Hello, World !
{HEADER}
And here's the content ;-)
TPL;
define("NAME","Site Name");
$array = array("HEADER" => "Welcome to ".NAME."'s website!");
foreach($array as $var => $content) {
$template = str_replace("{" . strtoupper($var). "}", $content,$template);
}
var_dump($template);
And the output I get it :
string 'Hello, World !
Welcome to Site Name's website!
And here's the content ;-)' (length=73)
Which indicates it's working ;-)
(It wasn't, when $array was declared the way you set it)
When using this :
$array = array("HEADER","This is the header");
var_dump($array);
You are declaring an array that contains two items :
array
0 => string 'HEADER' (length=6)
1 => string 'This is the header' (length=18)
On the other hand, when using this :
$array = array("HEADER" => "This is the header");
var_dump($array);
You are declaring an array that :
contains only one item
"HEADER" being the key
and "This is the header" being the value
Which gives :
array
'HEADER' => string 'This is the header' (length=18)
When using foreach ($array as $key => $value), you need the second one ;-)
And, purely for reference, you can take a look at, in the manual, the following pages :
Arrays
foreach

Categories