Exploding php posts - php

id:10 Ivysaur Level:5
stored in side $_POST[A]
I'm trying just to grab the id (so the 10) and the name (which in this case is Ivysaur) and I want to store them in a session variable. But before I store them I'm trying to explode it so can split it into parts
$phoneChunks = explode("-", $_POST[A]);
echo "Raw Phone Number = $rawPhoneNumber <br />";
echo "First chunk = $phoneChunks[0]<br />";
echo "Second chunk = $phoneChunks[1]<br />";
echo "Third Chunk chunk = $phoneChunks[2]";
I am getting
Raw Phone Number =
First chunk = Id:10 Ivysaur Level:5
Second chunk =
Third Chunk chunk =
What am i doing wrong ???

preg_match("/id:(\d+) (.+?) Level:(\d+)/",$_POST['A'],$match);
list(,$id,$name,$level) = $match; // don't forget extra , at beginning of list!
Now you have the variables $id, $name and $level to do whatever you want with. Good luck from there :)

You are trying to explode on a dash when there is no dash in your string. Try this:
$phoneChunks = explode(" ", $_POST[A]);

Try this:
$chunk = explode(" ", $_POST['A']);
it should produce something like this:
Array
(
[0] => id:10
[1] => Ivysaur
[2] => Level:5
)

What am i doing wrong ???
You are not escaping $_POST['A']
$phoneChunks = explode(' ',hmtlentities($_POST['A']));
See: What are the best practices for avoiding xss attacks in a PHP site

Related

How to read integers separated by space from a file in php

I am trying to read a line where multiple numbers were separated by space using php. Initially I tried using fscanf however the issue is, as fscanf read one line at a time, it only reads the first number. I am confused what to do.
Sample Input
20 30 -5987 456 523
The best approach for this case is to use a combination of explode and file reading. The strategy is initially read the whole line as an string. Then use explode to store the all the number in an array. However in that case the array would a string array later on we can change the type of array element from String to integer. Here is how
<?php
$_fp = fopen("php://stdin", "r");
fscanf($_fp, "%d\n", $count);
$numbers = explode(" ", trim(fgets($_fp)));
foreach ($numbers as &$number)
{
$number = intval($number);
}
sort($numbers);
?>
$input = trim(fgets(STDIN));
$arr = explode(" ", $input);
foreach($arr as &$number){
$number = (int)$number;
}
If you want to eliminate white space from "fopen" function user "trim" function or surround variable with trim function.
Example :
echo "Please enter series limit : ";
$handles = fopen ("php://stdin","r");
$n = trim(fgets($handles));
So here we can remove white space in between the characters as well as at the end.

Trim unwanted characters from the end of the last element in an array

How do I modify the last element in an array?
The array looks like this:
$fields = array("firstName = 'Bob', ",
"lastName = 'Smith', ",
"email = 'bob#example.com', ",
"address = '123 anystreet', ");
The array is generated by a script which creates the values and adds the comma/space at the end of each string. I want to remove that comma/space from only the last element in that array. Keep in mind that the values could in fact contain a comma/space combination so only the last element and the last two characters of the last element need to be removed.
I've looked at the end() function but I don't think that is going to help since it just gets the value.
Edit Ok so I created this function/array so that I would only have one mysql function to update users. Sort of like a detect changes function and it only passes back the required/changed fields. I didn't realize there were problems associated with this approach. I thought that since I already had the mysql queries written in my old functions there shouldn't be an issue with this way. The file that it's in will not be accessible to the public. I'm going to use the best answer that works for me but I'm going to search for why this is problematic and I would appreciate comments/links as to what is wrong with this approach.
Like this!
end($array);
$key = key($array);
reset($array);
There's a shorthand way to do this, but it's easier to follow if it's broken out into pieces:
$index = count( $fields ) - 1;
$value = $fields[$index];
$fields[$index] = preg_replace( "/,\ $/", "", $value );
To change the value of the last numeric element:
$lastValue = array_pop($fields);
$fields[] = rtrim(', ',$lastValue);
If you are preparing these values for a query I would suggest storing everything without commas in an array then calling implode on that array when needed to prevent trailing comma problems
Array pop and push are the easiest way to do it for basic arrays. (I know that isn't technically the question but many people will come here looking for the answer in relation to simple arrays as well).
<?php
function update_last(&$array, $value){
array_pop($array);
array_push($array, $value);
}
?>
Then you can use the function like this:
<?php
$array = [1,2,3];
update_last($array, 4); //$array = [1,2,4];
?>
There are few ways:
1) For associative arrays, if you don't know the last element key, you better find the last element key first and change its value.
$array[end((array_keys($array)))] .= ' additional text';
2) if you don't know and don't care about keys, you can cut the last element and create a new one.
$array[] = array_pop($array).' additional text';
The last element of an array can always be retrieved using array_pop(), no matter how the array is indexed. It will also remove that element from the array, which is very useful if we want to modify and then add it again, as you cannot modify the element in-place.
What you are trying to do can be done with a simple, single line of code:
$fields[] = preg_replace("/, $/", "", array_pop($fields));
That's it. Here's what it does:
preg_replace() searches for a Regex pattern in a string and if found, replaces the match with an alternative string.
The pattern we search for is /, $/, which means: Match for ", " (comma + space) but only if it is at the very end of the string ($).
The replacement string is simply an empty string (""), thus the match is just deleted from the string.
The string we want to perform that replacement on is array_pop($fields), the last element of the array $fields, which is also removed from that array.
The modified string is then re-added to the array at the end ($fields[] = adds an element to an array without an explicit key and makes it the new last element).
Let's test it:
$fields = array(
"firstName = 'Bob', ",
"lastName = 'Smith', ",
"email = 'bob#example.com', ",
"address = '123 anystreet', ");
print "Before:\n\n";
print_r($fields);
$fields[] = preg_replace("/, $/", "", array_pop($fields));
print "\nAfter:\n\n";
print_r($fields);
Output:
Before:
Array
(
[0] => firstName = 'Bob',
[1] => lastName = 'Smith',
[2] => email = 'bob#example.com',
[3] => address = '123 anystreet',
)
After:
Array
(
[0] => firstName = 'Bob',
[1] => lastName = 'Smith',
[2] => email = 'bob#example.com',
[3] => address = '123 anystreet'
)
Note how the last comma is gone? Just try it yourself.
stumbled upon this today. i think the easiest non-pointer-breaking way would be:
array_splice($array, -1, 1, strtolower(end(array_values($array))).'blah' );
of course you can drop array_values if you dont have to care for the pointer.
but i wonder if this is a good way, since the extract-n-replace-stuff of splice could be more demanding than a pop or sth?
PHP 7 >= 7.3.0
$array[array_key_last($array)] = 'new value';
Demo
$fields = array(
"firstName = 'Bob', ",
"lastName = 'Smith', ",
"email = 'bob#example.com', ",
"address = '123 anystreet', "
);
$last = $fields[array_key_last($fields)];
$last = preg_replace( "/, $/", "", $last);
$fields[array_key_last($fields)] = $last;
I think PHP's Implode function might be a good alternative, instead of generating the commas yourself.
Barring that, you would have to use something like:
$lastfield = $fields[count($fields)-1];
$lastfield = str_split($lastfield,strlen($lastfield)-2);
$fields[count($fields)-1] = $lastfield;
The first and third lines are included to make the second line easier to read, but this could easily be compounded to one line.

PHP: uploading a text file and processing on the file content

I have a text file containing data/fields which are separated by exact column no. Each new line represents a new row of data.
Example of file content:
John Chow 26 543 Avenue Street
From the above, first 10 columns are for the name. Next two are for age. And the rest are for the address.
I need to segregate those data from the uploaded file and display it to the user in a formatted table, which will later on be inserted into the database upon confirmation by user.
I am new to PHP. I think substr could work.
Please guide me on how to go about it. I am using codeigniter with PHP, but basic steps in plain PHP will do. Thanks
Read every line of the file, and parse the lines with either substr or regular expression:
$data = array();
$h = fopen($uploadedfile,"r");
while (false !== ($line = fgets($h)))
{
/* substring way: */
$data[] = array(
'name' => trim(substr($line,0,10)),
'age' => intval(sbstr($line,10,2),10),
'address' => trim(substr($line,12))
);
/* regular expression way: */
preg_match("'^(.{10})(.{2})(.*)$'",$line,$n);
$data[] = array(
'name' => trim($n[1]),
'age' => intval($n[2],10),
'address' => trim($n3)
);
}
fclose($h);
Then iterate the $data array to display it in a table form.
Edit: what you ask in the comments can be done also with regular expressions. If $val is the parsed 10 character string, then:
$val = preg_replace("'^0*'","",$val);
would replace all leading 0s.
Yes, you should be using substr. This extracts part of the string. Something like:
$name = trim(substr($line, 0, 10));
$age = trim(substr($line, 10, 2));
$addr = trim(substr($line, 12));
I've added trim to remove any extra whitespace.
Umm I suggest you don't use substr, because peoples names are not always going to be the same length so this will create some problems. I think the explode and implode functions would do the trick better for you, they split a string into an array and back.
http://php.net/manual/en/function.explode.php
http://www.php.net/manual/en/function.implode.php
<?PHP
$str = "John Chow 26 543 Avenue Street";
$data = explode(" ", $str);
$first_name = $data[0];
$last_name = $data[1];
$age = $data[2];
$address = implode(" ", array_slice($data, 3));
?>
You can use a regexp:
if (preg_match('/(.{10})(.{2})(.{12})/', $input, $output)) {
var_dump($output);
}

extracting multiple fields from a text file using php

what is the best way of extracting multiple (~40 values) from a text file using php?
the data is more or less like:
NAMEA valuea
NAMEB valueb
I'm looking for a proper* approach to extracting this data into a data-structure, because i will need to specify regexs for all of them (all 40).
did i make myself clear?
*meaning, the default/painful method would be for me to do:
$namea = extractfunction("regexa", $textfilevalue);
$nameb = extractfunction("regeb", $textfilevalue);
... 40 times!
The lines may not be in the same order, or be present in each file. Every NAMEA is text like: "Registration Number:", or "Applicant Name:" (ie, with spaces in what i was calling as NAMEA)
Response to the Col.
i'm looking for a sensible "way" of writing my code, so its readable, modifiable, builds an object/array thats easily callable, etc... "good coding style!" :)
#Adam - They do actually... and contain slashes as well...
#Alix - Freaking marvelous man! THat was GOOD! would you also happen to have any insights on how I can "truncate" the rsultant array by removing everything from "key_x" and beyond? Should i open that as a new question?
Here is my take at it:
somefile.txt:
NAMEA valuea
NAMEB valueb
PHP Code:
$file = file_get_contents('./somefile.txt');
$string = preg_replace('~^(.+?)\s+(.+?)$~m', '$1=$2', $file);
$string = str_replace(array("\r\n", "\r", "\n"), '&', $string);
$result = array();
parse_str($string, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
Output:
Array
(
[NAMEA] => valuea
[NAMEB] => valueb
)
You may also be able to further simplify this by using str_getcsv() on PHP 5.3+.
EDIT: My previous version fails for keys that have spaces like #Col. Shrapnel noticed. I didn't read the question with enough attention. A possible solution since you seem to be using keys that always have : appended is this:
$string = preg_replace('~^(.+?):\s+(.+?)$~m', '$1=$2', $file);
To remove everything from key_x to the end of the file you can do something like this:
$string = substr($string, 0, strpos($string, 'key_x'));
So the whole thing would look like this:
somefile.txt:
Registration Number: valuea
Applicant Name: valueb
PHP Code:
$file = file_get_contents('./somefile.txt');
$string = substr($file, 0, strpos($file, 'key_x'));
$string = preg_replace('~^(.+?):\s+(.+?)$~m', '$1=$2', $string);
$string = str_replace(array("\r\n", "\r", "\n"), '&', $string);
$result = array();
parse_str($string, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
Output:
Array
(
[Registration_Number] => valuea
[Applicant_Name] => valueb
)
as far as I get it you can use file() to get an array of strings and then parse these strings with some regexp.
if you add a = sign between names and values, you'll be ble to get the whole thing at once using parse_ini_file()
Assuming your keys (namea, nameb) never have spaces in them:
$contents = file('some_file.txt'); // read file as array
$data = array();
foreach($contents as $line) { // iterate over file
preg_match('/^([^\s]+)\s+(.*)/', $line, $matches); // pull out key and value into $matches
$key = $matches[1];
$value = $matches[2];
$data[$key] = $value; // store key/value pairs in $data array
}
var_dump($data); // what did we get?

preg_replace all characters up to a certain one

I have a string
&168491968426|mobile|3|100|1&185601651932|mobile|3|120|1&114192088691|mobile|3|555|5&
and i have to delete, say, this part &185601651932|mobile|3|120|1& (starting with amp and ending with amp) knowing only the first number up to vertical line (185601651932)
so that in result i would have
&168491968426|mobile|3|100|1&114192088691|mobile|3|555|5&
How could i do that with PHP preg_replace function. The number of line (|) separated values would be always the same, but still, id like to have a flexible pattern, not depending on the number of lines in between the & sign.
Thanks.
P.S. Also, I would be greatful for a link to a good simply written resource relating regular expressions in php. There are plenty of them in google :) but maybe you happen to have a really great link
preg_replace("/&185601651932\\|[^&]+&/", ...)
Generalized,
$i = 185601651932;
preg_replace("/&$i\\|[^&]+&/", ...);
if you want real flexibility, use preg_replace_callback. http://php.net/manual/en/function.preg-replace-callback.php
Important: don't forget to escape your number using preg_quote():
$string = '&168491968426|mobile|3|100|1&185601651932|mobile|3|120|1&114192088691|mobile|3|555|5&';
$number = 185601651932;
if (preg_match('/&' . preg_quote($number, '/') . '.*?&/', $string, $matches)) {
// $matches[0] contains the captured string
}
It seems to me you ought to be using another data structure than a string to manipulate this data.
I'd want this data in a structure like
Array(
[id] => Array(
[field_1] => value_1
[field_2] => value_2
)
)
Your massive string can be massaged into such a structure by doing something like this:
$data_str = '168491968426|mobile|3|100|1&185601651932|mobile|3|120|1&114192088691|mobile|3|555|5&';
$remove_num = '185601651932';
/* Enter a descriptive name for each of the numbers here
- these will be field names in the data structure */
$field_names = array(
'number',
'phone_type',
'some_num1',
'some_num2',
'some_num3'
);
/* split the string into its parts, and place them into the $data array */
$data = array();
$tmp = explode('&', trim($data_str, '&'));
foreach($tmp as $record) {
$fields = explode('|', trim($record, '|'));
$data[$fields[0]] = array_combine($field_names, $fields);
}
echo "<h2>Data structure:</h2><pre>"; print_r($data); echo "</pre>\n";
/* Now to remove our number */
unset($data[$remove_num]);
echo "<h2>Data after removal:</h2><pre>"; print_r($data); echo "</pre>\n";

Categories