concatenate multiline string into one line string php - php

I am trying to format my mysql data to csv but for some reason when the code gets to physical address the text inside which is multi-lined brakes the output in the csv thus making it non usable.
i've tried trim(), strip_tags() on top of the cleanData() function;
function cleanData(&$str)
{
// escape tab characters
$str = preg_replace("/\t/", "\\t", $str);
// escape new lines
$str = preg_replace("/\r?\n/", "\\n", $str);
// convert 't' and 'f' to boolean values
if($str == 't') $str = 'TRUE';
if($str == 'f') $str = 'FALSE';
// force certain number/date formats to be imported as strings
if(preg_match("/^0/", $str) || preg_match("/^\+?\d{8,}$/", $str) || preg_match("/^\d{4}.\d{1,2}.\d{1,2}/", $str)) {
$str = "'$str";
}
// escape fields that include double quotes
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
}
which is echo'd for download with this code;
array_walk($rows,'cleanData');
$trows = implode(",", $rows)."\n";
echo $trows;
Is there a way to concatenate/combine a multi-lined string into a single line string without jumping through hoops?
The data is being retrieved from mysql table - which i loop through and add to the array:
foreach($row as $data)
{
if($data != '')
//echo $data.'<br>';
$tdata = strip_tags(trim($data));
array_push($rows, $tdata);
//echo $tdata.'<br>';
}
When it hits the physical address field, i am trying to combine/concatenate the string which is normally entered over a few lines, eg:
The Campus
Cnr Main & Sloane Street
Bryanston, Johannesburg
02021 South Africa
I want it as "The Campus Cnr Main & Sloane Street Bryanston Johannesburg 02021 South Africa"
or
"The Campus \n Cnr Main & Sloane Street\n Bryanston, Johannesburg\n 02021 South Africa"

I'm sorry, but your question incomplete, the code snippets are in a muddle and your variable names are inconsistent. For instance, you don't implode(',', $rows) for CSV. You implode(',', $cols) or implode(',', $row), and then implode("\n", $rows) (the latter only if you want the data to be in one single string).
I don't know whether your cleanData() function only fails to replace the newlines (the preg_replace looks ok) or if it's not called at all.
Your code
foreach($row as $data)
{
if($data != '')
//echo $data.'<br>';
$tdata = strip_tags(trim($data));
array_push($rows, $tdata);
//echo $tdata.'<br>';
}
is weird since you commented out a statement after an if clause without {}. I don't see any cleanData() calls here. Try to write an SSCCE and I'm quite sure you'll find the problem yourself while doing that.
Oh, to provide another approach for your question. You can do some replaces in SQL already:
select REPLACE(col, "\n", "\\n") from table

I a found solution that fixed my problem from this post;
How to remove line breaks (no characters!) from the string?
Fox's answer fixed it =D

Related

PHP - Search, put letters written in bold

I'm trying to do a search engine where I write in a textbox, for example, "Mi" and it selects and shows "Mike Ross". However it's not working with spaces. I write "Mike" and I get "Mike Ross", but when I write "Mike " I get "Mike Ross" (no bold).
The same is happening with accents.
So I write "Jo" and the result is "João Carlos". If I write "Joa", the result is "João Carlos" (without any bold part). I want to ignore the accents while writing but still display them in the results.
So this is my script after the SELECT:
while($row = $result->fetch_array()) {
$name = $row['name'];
$array = explode(' ',trim($name));
$array_length = count($array);
for ($i=0; $i<$array_length; $i++ ) {
$letters = substr($array[$i], 0, $q_length);
if (strtoupper($letters) == strtoupper($q)) {
$bold_name = '<strong>'.$letters.'</strong>';
$final_name = preg_replace('~'.$letters.'~i', $bold_name, $array[$i], 1);
$array[$i] = $final_name;
}
array[$i] = array[$i]." ";
}
foreach ($array as $t_name) { echo $t_name;
}
Thank you for your help!
if (strtoupper($letters) == strtoupper($q))
This will never evaluate to "true" with spaces since you're removing spaces from the matchable letter set with explode(' ', trim($name), effectively making any value of $q with a space unmatchable to $letters
Here's a quick example that does what I think you're looking for
<?php
$q = "Mike "; // User query
$name = "Mike Ross"; // Database row value
if(stripos($name, $q) !== false) // Case-insensitive match
{
// Case-insensitive replace of match with match enclosed in strong tag
$result = preg_replace("/($q)/i", '<strong>$1</strong>', $name);
print_r($result);
}
// Result is
// <strong>Mike </strong>Ross
From what I can tell (a quick google for "replace accented characters PHP"), you're kind of out of luck with that one. This question provides a quick solution using strtr, and this tip uses a similar method with str_replace.
Unfortunately, these rely on predefined character sets, so incoming accents you haven't prepared for will fail. You may be better off relying on users to enter the special characters when they search, or create a new column with a "searchable" name with the accented characters replaced as best as you can, and return the real name as the "matched" display field.
One more Note
I found another solution that can do most of what you want, except the returned name will not have the accent. It will, however, match the accented value in the DB with a non-accented search. Modified code is:
<?php
$q = "Joa";
$name = "João Carlos";
$searchable_name = replace_accents($name);
if(stripos($searchable_name, $q) !== false)
{
$result = preg_replace("/($q)/i", '<strong>$1</strong>', $searchable_name);
print_r($result);
}
function replace_accents($str) {
$str = htmlentities($str, ENT_COMPAT, "UTF-8");
$str = preg_replace('/&([a-zA-Z])(uml|acute|grave|circ|tilde);/','$1',$str);
return html_entity_decode($str);
}

PHP exploding a string while keeping delimiters

For my project I needed to analyze different sentences and work out which ones were questions by determining if they ended in question marks or not.
So I tried using explode but it didn't support multiple delimiters. I temporarily replaced all punctuation to be chr(1) so that I could explode all sentences no matter what they ended with (., !, ?, etc...).
Then I needed to find the last letter of each sentence however the explode function had removed all of the punctuation, so I needed some way of putting it back in there.
It took me a long time to solve the problem but eventually I cracked it. I am posting my solution here so that others may use it.
$array = preg_split('~([.!?:;])~u',$raw , null, PREG_SPLIT_DELIM_CAPTURE);
Here is my function, multipleExplodeKeepDelimiters. And an example of how it can be used, by exploding a string into different sentences and seeing if the last character is a question mark:
function multipleExplodeKeepDelimiters($delimiters, $string) {
$initialArray = explode(chr(1), str_replace($delimiters, chr(1), $string));
$finalArray = array();
foreach($initialArray as $item) {
if(strlen($item) > 0) array_push($finalArray, $item . $string[strpos($string, $item) + strlen($item)]);
}
return $finalArray;
}
$punctuation = array(".", ";", ":", "?", "!");
$string = "I am not a question. How was your day? Thank you, very nice. Why are you asking?";
$sentences = multipleExplodeKeepDelimiters($punctuation, $string);
foreach($sentences as $question) {
if($question[strlen($question)-1] == "?") {
print("'" . $question . "' is a question<br />");
}
}

I cannot get strpos to work with newline

I am very new to php and cannot find out how to fix this. I have a form and want to pass some string to it and have it checked with another file. It is working fine if all the strings are on the same line but as soon as I put in multiple lines of string, it will fail.
I have a php file with the following code:
<?php
echo "<center><form method='post' enctype='multipart/form-data'>";
echo "<b></b><textarea name='texttofind' cols='80' rows='10'></textarea><br>";
echo "<input name='submit' type='submit' style='width:80px' value='Run' />";
echo "</form></center>";
$texttofind = $_POST['texttofind'];
if(get_magic_quotes_gpc()) {
$texttofind = stripslashes($texttofind);
}
$texttofind = html_entity_decode($texttofind);
$s = file_get_contents ("/home/xxxxx/public_html/abc.txt");
if (strpos ($s, $texttofind) === false) {
echo "not found";
}
else
echo "found";
?>
and in abc.txt, I have
dog
cat
rat
Whenever, I open the php page and type in just dog or cat, it will be fine and show 'found' message but when I type multiple lines like 'dog<enter on keyboard>cat' and click submit button, it will return with the 'not found' message.
What is wrong with the code or anyway to adapt it so that it will be able to search multiple lines?
Thank you in advance.
When you place your search words on new lines you are adding characters that do not exist in your comparison file. Eg when you enter...
dog
cat
rat
You are actually sending a string that looks like...
"dog\ncat\nrat"
Where \n means character 13 or the standard non windows new line character. The fix for this depends on what you want to do. You can search for results using PHP's explode function to convert the input string into an array and then get positions for each word...
$inputs = explode("\n", $_POST['field']);
$positions = array();
foreach($inputs as $val)
$positions[] = str_pos($compareTo, $val);
Now $positions should be an array of the str_pos's that where found for each line.
If you are still trying to search that the comparison file has all of the text you just don't care if it is on a new line or not you can simply strip out the new line characters all together (also remove \r just to be safe)
$inputs = str_replace("\n", "", $_POST['field']);
$inputs = str_replace("\r", "", $inputs);
Now inputs would be "dogcatrat". You can use the second argument of str_replace to set a space instead of a \n to get back to the space separated list.
$inputs = str_replace("\n", " ", $_POST['field']);
$inputs = str_replace("\r", "", $inputs);
Yes we are still ignoring \r all together (silly windows). All the same I suggest reading up on how to use array's, explode & implode and str_replace. Many will comment on this and tell you that str_replace is bad and that you should learn regex. As an experienced developer I find very few cases where regex replacements provide any better functionality in simple character replacement and it will cause you to learn a completely new language of commands. For now ignore those who tell you to use regex but definitely learn regex in the near future. You will need it eventually, just not for something of this nature.
http://php.net/manual/en/language.types.array.php
http://php.net/manual/en/function.explode.php
http://php.net/manual/en/function.implode.php
http://php.net/manual/en/function.str-replace.php
http://php.net/manual/en/function.preg-match.php
<?php
$values=explode("\n",$txttofind);
foreach($values as $value)
{
if (strpos ($s, $value) === false)
{
echo "$value : not found <br>";
}
else
{
echo "$value : found <br>";
}
}
?>

How can I replace spaces with carriage returns using PHP?

I have a few strings
Computer Stations
Monitors
Indian Reserve
How do i replace spaces in a variable with carriage returns "\r"? How can I determine if a replacement was made so I can add a CSS class in my output.
My PHP is below and basically for CSS purposes i need to force a carriage return on two words and if the string is a single word then give the class "single" so i can style it differently...any ideas
$key "Computer Stations"
echo "<li>{$key}</li>";
$key "Monitors"
echo "<li>{$key}</li>";
$key "Indian Reserve"
echo "<li>{$key}</li>";
If I understand you correctly:
if (strpos($str, ' ') !== false) {
// there is space in string, do something
}
If you want to replace space to something:
str_replace(' ', "\n", $string);
In this case str_replace replaces every space to newline symbol.
Following code will replace all spaces with return symbol ("\r") and if there isn't any, set variable $class to "single".
$newString = str_replace(" ", "\r", $oldString, $count);
if($count == 0) {
$class = "single";
}
echo "<li><a class=\"$class\">$newString</a></li>";
By return you mean newline? If so, you should use "\n" instead of "\r". If you would like to see the newline in a browser not just in the code you should use '<br />' instead.
To check presence of any string inside another, use the PHP strpos() function:
if (strpos($key, " ") !== FALSE) {
// There is a space
}
else {
// No space in string
}

enclosure parameter in fputcsv not behaving as expected

This I believe has a simple explanation, I just cannot see it. I want to generate a pretty simple csv delimetered file with double quotes around field values.
As per the manual page on fputcsv(), I try to pass on the delimiter and enclosure argument explicitly to have double-quoted field values required for data import in third-party application as in function call below:
// relevant line of codes ...
while($row = mysql_fetch_array($result)){
$name_pieces = "";
$name_pieces = explode(" ", $row['name']);
$numberOfPieces = count($name_pieces);
$lastNameIndex = $numberOfPieces - 1;
$lastname = $name_pieces[$lastNameIndex];
$firstname = $name_pieces[0];
} // Line array becomes the first, second, third fields in resulting .csv output.
$line = array( $row['username'],
$row['name'],
$firstname,
$lastname,
$row['description'] );
$data[] = $line;
}
foreach($data as $dataLine){
if(fputcsv($fh, $dataLine, ',', '"') === false){
die("Unable to write to csv file.");
}
}
Following is a sample of the script's .csv output, notice that only second and last fields are quoted.
AG,"Alan Gaulois",Alan,Gaulois,"(AG) Alan Gaulois"
COMMIS,commis,commis,commis,"(COMMIS) commis"
DU,"Denis Fargo",Denis,Fargo,"(DF) Denis Fargo"
Anyone have an idea why the fields are not all quoted? I could well have missed something on doc page, any insight appreciated!
To my knowledge, yes, delimiters are only needed if there are spaces, if you need something else, consider using array_map.
Something like:
function surroundWithQuotes ($input)
{
$input = str_replace('"', '""', $input); //escaping in csv files is done by doing the same quote twice, odd
return '"' . $input . '"';
}
foreach($data as $dataLine){
if(fputcsv($fh, array_map("surroundWithQuotes" $dataLine),$dataLine, ',', '') === false){
die("Unable to write to csv file.");
}
}
the function just sets quotes, if necessary. If there is no space, special char or quote inside the string you want to write, no enclosing quotes are needed.
The $enclosure argument doesn't tell the parser "you have to quote everything", but it tells the parser, which char to use to quote (by default it is ", so you don't have to write it).
There's something missing in the above mentioned answers, the predicate or call back function would return "" in case of an empty string.
Ideally it should be.
function encloseWithQuotes($value)
{
if (empty($value)) {
return "";
}
$value = str_replace('"', '""', $value);
return '"'.$value.'"';
}

Categories