charco Posted October 3, 2019 Share Posted October 3, 2019 Hi there. I have a javascript code that packages an array as a string and sends it to a php mailer, which then separates the string into an array for mailing using a preg_split regular expression that searches for a comma followed by an html tag. $myWrongArray = preg_split("/,(?=<)/",$myVar); // lookahead splits the string when the comma is before a tag (the opening bracket < ) //The look ahead is (?=<), which interrogates the next character and if it is the angle bracket, <, the preg_split function operates. Everything works great EXCEPT when the string contains a degree sign or an &, in which case the array is returned up to the degree or & and then stops. I can’t for the life of me understand it. Any ideas? Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/ Share on other sites More sharing options...
requinix Posted October 3, 2019 Share Posted October 3, 2019 The problem is somewhere else. What's the rest of your code? And at what point are you seeing that the entries are cut off? Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570287 Share on other sites More sharing options...
charco Posted October 4, 2019 Author Share Posted October 4, 2019 An array is sent from javascript to the php mailer via a (relatively long) string. The string contains html tags and also it has commas in the middle of some of the array members. To split the string back into an array for the php mailer I use the regex with a look forward, as explained above. Everything works perfectly UNLESS the string contains a degree sign, º, or an ampersand, &, in which case the php output simply does not show any more of the array. It doesn't break the program, but the array after the degree sign, º, or an ampersand, &, is no longer shown. For example if javascript sends: var wrongArray = "<p>This is my question 1,</p><p>This is my question 2,</p><p>This is my question 3,</p><p>This is my question 4,</p>"; Gets sent using the postIt() function below function postIt() { var http = new XMLHttpRequest(); var url = "../mail/testSum.php"; var params = "realname="+myName+"&rightAnswers="+correct+"&percentageScore="+percentage+"&wrongArray="+wstore+"&asked="+numq+"&mins="+minutes+"&secs="+seconds+"&deliver="+destination+"&testName="+test; http.open("GET", url+"?"+params, true); http.onreadystatechange = function() { //Call a function when the state changes. if(http.readyState == 4 && http.status == 200) { //alert(http.responseText); } } http.send(null); } This is then received by the php mailer: $myVar=$_GET["wrongArray"]; which is then split into an array using preg_split() $myWrongArray = preg_split("/,(?=<)/",$myVar); The resulting array is output to the email message in the middle of an unordered list: foreach($myWrongArray as $my_Array){ $message .= "\r\n\r\n<li style='font-family:verdana;font-size:12px;color:teal'>".$my_Array."</li>"; } The whole php looks like this: <?php error_reporting(E_ALL); $data1=$_GET["realname"]; $data2=$_GET["rightAnswers"]; $data3=$_GET["asked"]; $data4=$_GET["mins"]; $data5=$_GET["secs"]; $data6=$_GET["percentageScore"]; $data7=$_GET["deliver"]; $data8=$_GET["testName"]; $myVar=$_GET["wrongArray"]; $emailList = "xxx@gmail.com".","."xxyy@gmail.com"; $myWrongArray = preg_split("/,(?=<)/",$myVar); $sendTo = $data7; $subject = $data8." summary results for ".$data1; $headers = "MIME-Version: 1.0" . "\n"; $headers .= "Content-type:text/html;charset=UTF-8" . "\n"; $headers .= "bcc: $emailList\r\n"; $headers .= "From: " . $data1. "<" . "results@ibchem.com".">\r\n"; $headers .= "Reply-To: " . $data7 . "\r\n"; $headers .= "Return-path: " . $data7. "\r\n"; // now we can add the content of the message to a body variable $message = "<html><head><title>Online test - ".$data8."</title></head><body>"; $message .= "<p style='font-family:verdana;font-size:12px;color:blue'>".$data1.", you have attempted ".$data3. " questions"; $message .= " in ".$data4." minutes and ".$data5." seconds"; $message .= " and scored a total of ".$data2.".</p>"; $message .= " <p style='font-family:verdana;font-size:12px;color:blue'>Final percentage = ".$data6."%</p>\r\n\r\n"; $message .= "<p style='font-family:verdana;font-size:12px;color:blue'>The following questions were answered incorrectly: </p><hr /><ul>"; foreach($myWrongArray as $my_Array){ $message .= "\r\n\r\n<li style='font-family:verdana;font-size:12px;color:teal'>".$my_Array."</li>"; } //$message = strip_tags($message); $message .= "</ul><hr /></body></html>"; // finally, send the email mail($sendTo, $subject, $message, $headers); ?> Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570289 Share on other sites More sharing options...
charco Posted October 4, 2019 Author Share Posted October 4, 2019 OK, I think that I'm getting closer. It's not the array or the preg_split that's the problem, it's the html email which is not rendering the degree symbol, or any other unusual character. I am using: // put the headers in place $headers = "MIME-Version: 1.0" . "\n"; $headers .= "Content-type:text/html;charSet=utf-8" . "\n"; $headers .= "bcc: $emailList\r\n"; $headers .= "From: " . $data1. "<" . "xxx@gmail.com".">\r\n"; $headers .= "Reply-To: " . $data7 . "\r\n"; $headers .= "Return-path: " . $data7. "\r\n"; // now we can add the content of the message to a body variable $message = "<!DOCTYPE html>"; $message .= "<html><head><title>Online test - ".$data8."</title></head><body>"; $message .= "<p style='font-family:verdana;font-size:12px;color:blue'>".$data1.", you have attempted ".$data3. " questions"; $message .= " in ".$data4." minutes and ".$data5." seconds"; $message .= " and scored a total of ".$data2.".</p>"; $message .= " <p style='font-family:verdana;font-size:12px;color:blue'>Final percentage = ".$data6."%</p>\r\n\r\n"; $message .= "<p style='font-family:verdana;font-size:12px;color:blue'>The following questions were answered incorrectly: </p><hr /><ul>"; foreach($myWrongArray as $my_Array){ $message .= "\r\n\r\n<li style='font-family:verdana;font-size:12px;color:teal'>".$my_Array."</li>"; } $message .= "</ul><hr /></body></html>"; // finally, send the email mail($sendTo, $subject, $message, $headers); Can anyone see why the email is not showing the degree character? Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570290 Share on other sites More sharing options...
requinix Posted October 4, 2019 Share Posted October 4, 2019 An ampersand will cause problems if you inject the value into a query string. Use encodeURIComponent. Or better yet, don't send such free-form data through the query string and POST it instead. Which is what you should be doing anyways because the request causes something to happen on the backend (sending an email) and that should not be triggerable through a simple GET request. For the degree sign, do other non-standard symbols break? Accented characters? Greek or Cyrillic? Fancy symbols not on the keyboard? Check your character encodings. Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570294 Share on other sites More sharing options...
Zane Posted October 4, 2019 Share Posted October 4, 2019 So, if I'm understanding correctly, you have this HTML <p>This is my question 1,</p><p>This is my question 2,</p><p>This is my question 3,</p><p>This is my question 4,</p> And you want to turn it into this? Array ( [0] => "This is my question 1" [0] => "This is my question 2" [0] => "This is my question 3" [0] => "This is my question 4" ) If that's the case, then you can just load it into a DOMDocument, something like this. $dom = new DOMDocument; $dom->loadHTML("<p>This is my question 1,</p><p>This is my question 2,</p><p>This is my question 3,</p><p>This is my question 4,</p>"); $paragraphs = $dom->getElementsByTagName('p'); $paragraph_values = array(); foreach ($paragraphs as $p) { $paragraph_values[] = $p->nodeValue } Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570295 Share on other sites More sharing options...
charco Posted October 5, 2019 Author Share Posted October 5, 2019 No, I have no problem with the array. I want php to be able to use special characters in the emails. But º and & stop the message from completing. Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570332 Share on other sites More sharing options...
requinix Posted October 5, 2019 Share Posted October 5, 2019 7 hours ago, charco said: No, I have no problem with the array. I want php to be able to use special characters in the emails. But º and & stop the message from completing. So does that mean what I said has helped you fix, or at least find, the source of the problem? Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570340 Share on other sites More sharing options...
charco Posted October 11, 2019 Author Share Posted October 11, 2019 I have identified that the source of the problem to be using GET rather than POST when passing data from javascript to php via AJAX. I am almost there, but there are still problems between the AJAX parcelling and the PHP unpacking. The javascript generates me an array in a function using: wstore.push(question+"<p style='color:teal'> Answer = "+ans+dim+"</p>"); To store the question and the answer in an array called wstore. So that everytime a question is answered incorrectly it goes into the array. When the quiz is finished the array is sent (as a string) to PHP for processing. function postIt() { var wrongArray = JSON.stringify(wstore); $.ajax({ type: "POST", url: '../mail/testSum.php', data: {wrongArray : wrongArray}, cache: false, success: function(){ //alert("OK"); } }); } In PHP the string is stored in a PHP variable: $myVar=$_POST["wrongArray"]; And then split back into an Array, using pregsplit to identify the commas that appear before a html tag $myWrongArray = preg_split("/,(?=<)/",$myVar); This is then displayed in the message for sending: foreach($myWrongArray as $my_Array){ $message .= "\r\n\r\n<li style='font-family:verdana;font-size:12px;color:teal'>".$my_Array."</li>"; } .. but it does not show as an unordered list :( I don't know where to go from here ... The output email is almost correct, but retains square brackets (from somewhere) and "," between questions (see image): Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570517 Share on other sites More sharing options...
Barand Posted October 11, 2019 Share Posted October 11, 2019 It looks like your output is a single string ... $output = '["1.Question text 1 blah blah","2.Question text 2 blah blah","3.Question text 3 blah blah","4.Question text 4 blah blah"]'; … (a json-encoded array) which is why you get a single <li> item. However, you should get the required result if you ... $questions = json_decode($output, true); echo "<ul>"; foreach ($questions as $q) { echo "<li>$q</li>"; } echo "</ul>"; Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570518 Share on other sites More sharing options...
charco Posted October 11, 2019 Author Share Posted October 11, 2019 Yes, that's it! I gave it a go and it is EXACTLY the answer. Thank you all contributors very much for your patience. Quote Link to comment https://forums.phpfreaks.com/topic/309325-regex-breaks-down-when-it-encounters-a-%C2%BA-sign-or-an/#findComment-1570519 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.