php regular expression matches and replacement - php

again.
I'm trying to go through a database table and replace all instances of old BBCode (ie: [i:fs8d979]) and replace it with simple BBCode ([i]). However, I'm getting very confusing results.
$root_path = './';
include($root_path.'includes/common.php');
$posts = array();
$sql = 'SELECT post_id, post_text FROM posts';
$db->query($sql);
while($row = $db->fetch_assoc())
{
$posts[]['id'] = $row['post_id'];
$posts[]['text'] = $row['post_text'];
}
foreach($posts as $post)
{
$regex = "/\[(\D)(\:[a-zA-Z0-9_]{1,})\]/";
if(preg_match($regex, $post['text'], $matches))
{
$string = preg_replace('/'.$matches[2].'/', '', $post['text']);
$sql = 'UPDATE posts SET post_text = "'.$string.'" WHERE post_id = '.$post['id'];
$db->query($sql);
echo $post['id'].'--Matched and replaced<br />';
}
else
{
echo $post['id'].'--No Match<br />';
}
}
echo 'done';
when i run this script, I get output like this:
1302--No Match
--No Match
1303--No Match
--No Match
17305--No Match
--Matched and replaced
5532--No Match
--No Match
17304--No Match
--No Match
1310--No Match
--No Match
it would appear that the script is attempting to do everything twice, and I'm not sure why. The database fields are not getting updated either.
I've echoed everything out for debugging purposes, and all variables are set and everything looks like it should be working properly.
Any suggestions?

At the point in the code:
while($row = $db->fetch_assoc())
{
$posts[]['id'] = $row['post_id'];
$posts[]['text'] = $row['post_text'];
}
You are creating two entries in the array, one with the id, followed by the text.
I think you want:
while($row = $db->fetch_assoc())
{
$posts[] = array('id' => $row['post_id'], 'text' => $row['post_text']);
}
It would explain why each one is happening twice and nothing is changing.
The debug was showing the wrong value too:
echo $post['id'].'--Matched and replaced<br />';
and the output was
--Matched and replaced which showed no post id.

First: the lines
$posts[]['id'] = $row['post_id'];
$posts[]['text'] = $row['post_text'];
are adding two elements to the $posts array. That is why you are getting two outputs per post.
Second: I don't think the colon : is a special character - it doesn't need to be escaped. So it should look like:
$regex = "/\[(\D)(:[a-zA-Z0-9_]+)\]/";

Related

How to use string variable that have special character "#" in select query statement mysql php

<?php
include('dbLink2.php');
$quizqr = $_GET['quizQR'];
$recordsID1 = $_GET['recordsID1'];
$recordsID2 = $_GET['recordsID2'];
$m_array1=array();
$m_array=array();
$sql = "SELECT quizQR, recordsID FROM `registertestactivity` WHERE (quizQR = '$quizqr' OR recordsID = '$recordsID1' OR recordsID = '$recordsID2') LIMIT 1";
$result = #mysqli_query($link, $sql) or die();
if (#mysqli_affected_rows($link) > 0) {
while($row = #mysqli_fetch_assoc($result))
{
$m_array[]=$row;
}
} else {
$m_array1 += ["quizQR" => "NoRecords"];
$m_array1 += ["recordsID" => "NoRecords"];
$m_array[0] = $m_array1;
}
echo json_encode($m_array);
#mysqli_free_result($result);
#mysqli_close($link);
?>
Can someone help me out, i have tried the mysqli_real_escape_string and it still doesnt work :(
The $quizqr value has a '#' character in the string and this is the error msg that pops when the ajax call this php:
Because you have a # in the URL you're dealing with a URL Fragment which means that everything past the # is not available in the query string. PHP offers a flag, PHP_URL_FRAGMENT for its parse_url() function which can help you get what you need from the string.
Here is one example using the URL you provided:
$fragment = parse_url($url, PHP_URL_FRAGMENT);
echo $fragment;
$fragmentSection = explode('&', $fragment);
print_r($fragmentSection);
foreach($fragmentSection AS $section) {
if(0 != strpos($section, '=')) {
$sectionParts = explode('=', $section);
$queryParts[$sectionParts[0]] = $sectionParts[1];
}
}
print_r($queryParts);
This ultimately returns two array members which could then be used in your query:
Array
(
[recordsID1] => records_001
[recordsID2] => records_002
)
The best thing to do would be to write a function to which you pass the URL to return the elements you need.
Keep in mind that this is not fool-proof. If the URL is in a different format then what I have done here will have to be modified to work as you would like it to.
Additionally you have been given some warnings and guidance in the comments you should follow to keep your code safe and efficient, so I will not repeat them here.

PHP query with string contain quotes

Hi i need to do a request to mysql to get some data where filed name = $letter
but the variable $letter may contain '
my problem is this i try to use this :
$letter = mysqli_real_escape_string($conn,strtolower($letter));
$us = $conn->query("SELECT id FROM singers where trim(LOWER(name)) = '".$letter."'");
My problem is in if $letter was I'm legend, after executing this line it become I\'m legend so it can't be find in database because in database it's stored as i'm legend
how i can resolve this and get right result.
echo $letter;
$letter = mysqli_real_escape_string($conn,strtolower($letter));
echo $letter;
RESULT
i'm
i\'m
why you have used
trim and LOWER in your column name
"SELECT id FROM singers where trim(LOWER(name)) = '".$letter."'" //why trim and LOWER
use this
"SELECT id FROM singers where name = '".$letter."'"
Also try this like
$letter = mysqli_real_escape_string($conn,strtolower($letter));
$sql = "SELECT id FROM singers where name = '".$letter."'";
// echo $sql; die; print this and run in phpmyadmin to check
$us = $conn->query($sql);
if ($us !== false) {
echo 'done';
}
else{ die('failed!' . mysqli_error($conn));}
there is difference between field and value in where
the \ added is the problem

PHP bad word replacement comment system

I'm trying to create a comment system using php that replaces a commenters bad words with ****. I'm using sql and have a database with two columns, one with the bad word and one with the replacement word (which is the ****). So far, I am able to identify when a user types in a determined bad word and retrieve the replacement word for it, however I am unable to replace that bad word with the replacement word. I tried to do $element = $goodWord after $goodWord = $row['replaceWord'] to say that the new identified bad word should be replaced, however it does nothing. I'm not exactly sure how to set an element within an array in php to a new value. Any suggestions?
code:
if(!empty($_GET["field1_name"])) {
$field1_name = mysqli_real_escape_string($link, $_GET["field1_name"]);
$field1_name_array = explode(" ",$field1_name);
foreach($field1_name_array as $element){
$query = "SELECT replaceWord FROM changeWord WHERE badWord = '$element' ";
$query_link = mysqli_query($link,$query);
if(mysqli_num_rows($query_link)>0){
$row = mysqli_fetch_assoc($query_link);
$goodWord = $row['replaceWord'];
$element = $goodWord
}
}
}
if(!empty($_GET["field1_name"])) {
$field1_name = mysqli_real_escape_string($link, $_GET["field1_name"]);
$field1_name_array = explode(" ",$field1_name);
$newComment = '';
foreach($field1_name_array as $element){
$query = "SELECT replaceWord FROM changeWord WHERE badWord = '$element' ";
$query_link = mysqli_query($link,$query);
if(mysqli_num_rows($query_link)>0){
$row = mysqli_fetch_assoc($query_link);
$goodWord = $row['replaceWord'];
$element = $goodWord
}
$newComment = $newComment." ".$element; // append $element back to back to create modified comment
}
// now update the $newComment back to your comment Table
}

Get Popular words in PHP+MySQL

How do I go about getting the most popular words from multiple content tables in PHP/MySQL.
For example, I have a table forum_post with forum post; this contains a subject and content.
Besides these I have multiple other tables with different fields which could also contain content to be analysed.
I would probably myself go fetch all the content, strip (possible) html explode the string on spaces. remove quotes and comma's etc. and just count the words which are not common by saving an array whilst running through all the words.
My main question is if someone knows of a method which might be easier or faster.
I couldn't seem to find any helpful answers about this it might be the wrong search patterns.
Somebody's already done it.
The magic you're looking for is a php function called str_word_count().
In my example code below, if you get a lot of extraneous words from this you'll need to write custom stripping to remove them. Additionally you'll want to strip all of the html tags from the words and other characters as well.
I use something similar to this for keyword generation (obviously that code is proprietary). In short we're taking provided text, we're checking the word frequency and if the words come up in order we're sorting them in an array based on priority. So the most frequent words will be first in the output. We're not counting words that only occur once.
<?php
$text = "your text.";
//Setup the array for storing word counts
$freqData = array();
foreach( str_word_count( $text, 1 ) as $words ){
// For each word found in the frequency table, increment its value by one
array_key_exists( $words, $freqData ) ? $freqData[ $words ]++ : $freqData[ $words ] = 1;
}
$list = '';
arsort($freqData);
foreach ($freqData as $word=>$count){
if ($count > 2){
$list .= "$word ";
}
}
if (empty($list)){
$list = "Not enough duplicate words for popularity contest.";
}
echo $list;
?>
I see you've accepted an answer, but I want to give you an alternative that might be more flexible in a sense: (Decide for yourself :-)) I've not tested the code, but I think you get the picture. $dbh is a PDO connection object. It's then up to you what you want to do with the resulting $words array.
<?php
$words = array();
$tableName = 'party'; //The name of the table
countWordsFromTable($words, $tableName)
$tableName = 'party2'; //The name of the table
countWordsFromTable($words, $tableName)
//Example output array:
/*
$words['word'][0] = 'happy'; //Happy from table party
$words['wordcount'][0] = 5;
$words['word'][1] = 'bulldog'; //Bulldog from table party2
$words['wordcount'][1] = 15;
$words['word'][2] = 'pokerface'; //Pokerface from table party2
$words['wordcount'][2] = 2;
*/
$maxValues = array_keys($words, max($words)); //Get all keys with indexes of max values of $words-array
$popularIndex = $maxValues[0]; //Get only one value...
$mostPopularWord = $words[$popularIndex];
function countWordsFromTable(&$words, $tableName) {
//Get all fields from specific table
$q = $dbh->prepare("DESCRIBE :tableName");
$q->execute(array(':tableName' = > $tableName));
$tableFields = $q->fetchAll(PDO::FETCH_COLUMN);
//Go through all fields and store count of words and their content in array $words
foreach($tableFields as $dbCol) {
$wordCountQuery = "SELECT :dbCol as word, LENGTH(:dbCol) - LENGTH(REPLACE(:dbCol, ' ', ''))+1 AS wordcount FROM :tableName"; //Get count and the content of words from every column in db
$q = $dbh->prepare($wordCountQuery);
$q->execute(array(':dbCol' = > $dbCol));
$wrds = $q->fetchAll(PDO::FETCH_ASSOC);
//Add result to array $words
foreach($wrds as $w) {
$words['word'][] = $w['word'];
$words['wordcount'][] = $w['wordcount'];
}
}
}
?>

array_unique only on one field?

I have following code for an autocomplete box, I'm adding an image for choice clarification but want to make sure the title returned is unique, but, when I get to the code which makes the array unique, i've added other code which makes it non unique in other areas. Is there a way around this?
$query = "SELECT $title, imageURL FROM PRprodINFO2 WHERE ((prodcatID = '$cat_id')
AND ($title LIKE \"%" . $_GET["q"] . "%\")) group by $title LIMIT 8";
}
$result = mysql_query($query);
// set the array
$output_items = array();
while($row = mysql_fetch_array($result)) {
// clean after first non letter/number
$row[$title] = preg_replace('/[^\w\s].*$/', "", $row[$title]);
//trim spaces
$row[$title] = trim($row[$title]);
// add image src
$output_items[] = '<img src='.$row[imageURL].' style=max-width:50px;>'
.$row[$title];
} // while
// here i need just $row[title] to be unique,
// it is made non unique after regex strips off some characters
$output = array_unique($output_items);
print(implode("\n", $output));
mysql_close();
I am possibly confused by what you are asking. It seems like you would already have unique titles since you are grouping by title in your sql. But, maybe you have extra non alpha-numeric characters you are stripping out with your regex that makes some unique titles the same.
In that case, instead of building up your $output_items like you are, try:
$output_items[$row['title']] = $row['imageURL'];
This will ensure that each title is unique. You will have the imageURL of the last row that matched that title. If you want, instead, the first title that matched, then just check isset before overwriting it like:
if (!isset($output_items[$row['title']])) $output_items[$row['title']] = $row['imageURL'];
Then, outside of the loop, build up your output string.
$output = '';
foreach ($output_items as $title => $image) {
$output .= '<img src='.$image.' ...>'.$title."\n";
}
echo $output;

Categories