PHP Remove All Non-alphanumeric Characters Except Apostrophes - preg-replace

$keywords = explode("\n",$_POST['keywords']);
//Inserting into Database
foreach($keywords as $key => $keyword){
$keyword = strtolower(trim($keyword));
$keyword = preg_replace("/[^A-Za-z0-9' ]/", "", $keyword);
$keyword = preg_replace("/\s+/", " ", $keyword);
$insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('$keyword')";
mysql_query($insertkeywords);
}
I can't for the life of me figure out why this code won't insert the keywords into the database when I have an apostrophe in the:
"/[^A-Za-z0-9' ]/"
But when I remove it to be:
"/[^A-Za-z0-9 ]/"
This script inserts records into the database.
What am I trying to do?
I have a textarea on a form. For each keyword on a new line, I explode based on the \n. I want to remove all non-letter and non-number characters from the keywords but don't want apostrophes to be removed.
I basically want all keywords to be lower-case with leading, trailing and extra white spaces - 2 or more blank spaces trimmed down to one - removed along with any non-letter and non-number characters except for apostrophes.

You need to escape your keyword: $insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('".mysql_real_escape_string($keyword)."')";

Thank you clover. Without your help, it would have taken me many hours to figure that one out! I ended up using mysqli_real_escape_string instead of mysql_real_escape_string because mysql_real_escape_string says it is deprecated as of PHP 5.5.0. As a result, I had to change it up a bit but the below code seems to work great for me so far (in case anyone else runs across this).
$con = mysqli_connect("localhost","username","password");
if (!$con)
{
die('Could not connect: ' . mysqli_error());
}
else
{
echo "Connected Successfully!";
}
//select database
mysqli_select_db($con, "test");
$keywords = explode("\n",$_POST['keywords']);
//Inserting into Database
foreach($keywords as $key => $keyword){
$keyword = preg_replace("/[^A-Za-z0-9' ]/", " ", $keyword);
$keyword = preg_replace("/\s+/", " ", $keyword);
$keyword = strtolower(trim($keyword));
//$insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('$keyword')";
$insertkeywords = "INSERT IGNORE INTO kwdb (keyword) VALUES ('".mysqli_real_escape_string($con, $keyword)."')";
mysqli_query($con, $insertkeywords);
}

Related

Why Laravel Request object is replacing spaces with underscores on my form names?

I have a Form posting variables containing spaces in their names
e.g.
I perform my ajax request and i can see in chrome inspector that name is correctly passed "with blank space)
In my api.php:
Route::post('/user', 'UserController#get');
UserController
function get(Request $request)
{
dd($request->input('Name Surname')); //display null
dd($request->all()); //I notice the key's changed to Name_Surname
}
Taken that I can't change the names because they have to contain spaces (bad practice? ok but it has to be like that):
how can I avoid spaces to be replaced?
(maybe without to have to manipulate the request->all() returned array keys by hand....)
Short answer I don't believe there to be such a way.
You can map the response with a bit of string replace though:
$data = $request->all()->mapWithKeys(function($item, $key) {
return [str_replace("_", " ", $key) => $item];
});
If it's something you want to apply across the board, you could possible rig up some middleware to apply it to all requests.
If previous answer not work for you, try this:
$data = collect($request->all())->mapWithKeys(function($item, $key) {
return [str_replace("_", " ", $key) => $item];
})->toArray();
You may also normalize the Input Name if it is known...
$field_name = 'FIELD NAME WITH SPACES';
$value = request( str_replace( ' ', '_', $field_name ) );

How to search word by word using this approach (datatables)?

Here's the code I'm using it only search (starts with first letter to last) not word by word. How is it possible to make it word by word(keyword)?
<?php
/* Database connection start */
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "sample";
$conn = mysqli_connect($servername, $username, $password, $dbname) or die("Connection failed: " . mysqli_connect_error());
mysqli_set_charset($conn,"utf8");
/* Database connection end */
// storing request (ie, get/post) global array to a variable
$requestData= $_REQUEST;
$columns = array(
// datatable column index => database column name
0=> 'app_id',
1 =>'fullname',
);
// getting total number records without any search
$sql = "SELECT app_id";
$sql.=" FROM applicants";
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$totalData = mysqli_num_rows($query);
$totalFiltered = $totalData; // when there is no search parameter then total number rows = total number filtered rows.
$sql = "SELECT app_id, fullname";
$sql.=" FROM applicants WHERE 1=1";
if( !empty($requestData['search']['value']) ) { // if there is a search parameter, $requestData['search']['value'] contains search parameter
$sql.=" AND ( app_id LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR fullname LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR contact LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR address LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR photo LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR datereg LIKE '".$requestData['search']['value']."%' )";
}
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$totalFiltered = mysqli_num_rows($query); // when there is a search parameter then we have to modify total number filtered rows as per search result.
$sql.=" ORDER BY ". $columns[$requestData['order'][0]['column']]." ".$requestData['order'][0]['dir']." LIMIT ".$requestData['start']." ,".$requestData['length']." ";
/* $requestData['order'][0]['column'] contains colmun index, $requestData['order'][0]['dir'] contains order such as asc/desc */
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$data = array();
while( $row=mysqli_fetch_array($query) ) { // preparing an array
$nestedData=array();
$nestedData[] = $row["app_id"];
$nestedData[] = $row["fullname"];
$data[] = $nestedData;
}
$json_data = array(
"draw" => intval( $requestData['draw'] ), // for every request/draw by clientside , they send a number as a parameter, when they recieve a response/data they first check the draw number, so we are sending same number in draw.
"recordsTotal" => intval( $totalData ), // total number of records
"recordsFiltered" => intval( $totalFiltered ), // total number of records after searching, if there is no searching then totalFiltered = totalData
"data" => $data // total data array
);
echo json_encode($json_data); // send data as json format
?>
The problem: it'ss start to first letter to last letter not WORD by WORD. Is it possible to make it word by word?
source
You can use REGEXP and the [[:<:]] and [[:>:]] word-boundary markers to match words only.
For example:
SELECT *
FROM table
WHERE keywords REGEXP '[[:<:]]word[[:>:]]'
Also you need to escape data with mysqli_real_escape_string().
See updated code below:
// If there is a search parameter
if( !empty($requestData['search']['value']) ) {
$search = mysqli_real_escape_string(
$conn,
// Match beginning of word boundary
"[[:<:]]".
// Replace space characters with regular expression
// to match one or more space characters in the target field
implode("[[.space.]]+",
preg_split("/\s+/",
// Quote regular expression characters
preg_quote(trim($requestData['search']['value']))
)
).
// Match end of word boundary
"[[:>:]]"
);
$sql.=" AND ( app_id REGEXP '$search' ";
$sql.=" OR fullname REGEXP '$search' ";
$sql.=" OR contact REGEXP '$search' ";
$sql.=" OR address REGEXP '$search' ";
$sql.=" OR photo REGEXP '$search' ";
$sql.=" OR datereg REGEXP '$search' )";
}
As an alternative you may look into using full-text search.
If I understand you correctly - you're referring to the fact that the search is triggered by the keyup event in the search box. This javascript will allow the user to enter a word and then hit enter to perform the search.
This need to be added to the same js file that contains the datatables initialisation code, and goes AFTER the init code:
var oTable = $('#example').dataTable({
... yourdatatable init code
// unbind the keyup event that triggers the search
$("#example_filter input").unbind();
// use fnFilter() to perform the search when the `Return` key is pressed
$("#example_filter input").keyup(function (e) {
if (e.keyCode === 13) {
oTable.fnFilter(this.value);
}
});
This assumes datatables v1.9. If you're using 1.10 there's a SO answer here which outlines the modifications
working version -> https://jsfiddle.net/markps/HEDvf/3225/
here's the solution provided by: Gyrocode.com
// If there is a search parameter
if( !empty($requestData['search']['value']) ) {
$search = mysqli_real_escape_string(
$conn,
// Match beginning of word boundary
"[[:<:]]".
// Replace space characters with regular expression
// to match one or more space characters in the target field
implode("[[.space.]]+",
preg_split("/\s+/",
// Quote regular expression characters
preg_quote(trim($requestData['search']['value']))
)
).
// Match end of word boundary
"[[:>:]]"
);
$sql.=" AND ( app_id REGEXP '$search' ";
$sql.=" OR fullname REGEXP '$search' ";
$sql.=" OR contact REGEXP '$search' ";
$sql.=" OR address REGEXP '$search' ";
$sql.=" OR photo REGEXP '$search' ";
$sql.=" OR datereg REGEXP '$search' )";
}

inserting new line with OpenOffice::OODoc

I am having quite the issue creating a new line with this module and feel like I am just missing something.
my perl code looks like this:
use OpenOffice::OODoc;
my $name = "foo <br> bar";
$name=~s/<br>/\n/g;
my $outdir = "template.odt";
my $doc = ooDocument(file => $outdir);
my #pars = $doc->getParagraphList();
for my $p (#pars)
{
$doc->substituteText($p,'{TODAY}',$date);
$doc->substituteText($p,'{NAME}',$name);
...
Problem is when I open it in word or open office I have no newlines. Although if it open it in a text edit I have my new lines.. Any ideas of how to fix this?
Ok I figured it out, hopefully this will save someone hours of searching for the same thing. I added:
use Encode qw(encode);
ooLocalEncoding('utf8');
my $linebreak = encode('utf-8', "\x{2028}");
$doc->substituteText($p,'<br>', $linebreak);
So my final code looks like this:
use OpenOffice::OODoc;
use Encode qw(encode);
ooLocalEncoding('utf8');
my $linebreak = encode('utf-8', "\x{2028}");
my $outdir = "template.odt";
my $name = "foo <br> bar";
my $outdir = "template.odt";
my $doc = ooDocument(file => $outdir);
my #pars = $doc->getParagraphList();
for my $p (#pars)
{
$doc->substituteText($p,'{TODAY}',$date);
$doc->substituteText($p,'{NAME}',$name);
$doc->substituteText($p,'<br>', $linebreak);
...
Maybe not the best way to do things but it worked!
You could try and insert and empty para after the current one:
If the 'text' option is empty, calling this method is the equivalent
of adding a line feed.
This sequence (in a text document) inserts a linefeed immediately after paragraph 4. Replace 4 with current position.
$doc->insertElement
(
'//text:p', 4, 'text:p',
position => 'after',
text => '',
);

Lucene Search doesn't find keyword indexed fields

i save my fieldes with this code:
class Places_Search_Document extends Zend_Search_Lucene_Document{
public function __construct($class, $key, $title,$contents, $summary, $createdBy, $dateCreated)
{
$this->addField(Zend_Search_Lucene_Field::Keyword('docRef', "$class:$key"));
$this->addField(Zend_Search_Lucene_Field::UnIndexed('class', $class));
$this->addField(Zend_Search_Lucene_Field::UnIndexed('key', $key));
$this->addField(Zend_Search_Lucene_Field::Keyword('title', $title ,'UTF-8'));
$this->addField(Zend_Search_Lucene_Field::unStored('contents', $contents , 'UTF-8'));
$this->addField(Zend_Search_Lucene_Field::text('summary', $summary , 'UTF-8'));
//$this->addField(Zend_Search_Lucene_Field::UnIndexed('createdBy', $createdBy));
$this->addField(Zend_Search_Lucene_Field::Keyword('dateCreated', $dateCreated));
}
}
i search the word with this code:
$index = Places_Search_Lucene::open(SearchIndexer::getIndexDirectory());
$term = new Zend_Search_Lucene_Index_Term($q);
$query = new Zend_Search_Lucene_Search_Query_Wildcard($term);
$results = $index->find($query);
now it work perfect for unsorted and text fields , but it doesn`t search for keyword !!
Are you sure you really want those fields to be keyword analyzed? The keyword analyzer puts the whole text of the field as one token, which you rarely want.

Double Quote Problem after Saving an INI file with Zend_Config

I got a problem when I want to write and save an INI file. I use Zend_Config_Ini to handle this procedure.
The problem is I always got 'Double Quote' in the value for every line that use integer or number afer saving process. Here is the example
The original application.ini file
resources.session.use_only_cookies = 1
resources.session.remember_me_seconds = 86400
After I run these lines of code
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini',
null,
array('skipExtends' => true,
'allowModifications' => true));
// Modify a value
$config->production->resources->db->adapter = 'foobar';
// Write the config file
$writer = new Zend_Config_Writer_Ini(array('config' => $config,
'filename' => APPLICATION_PATH . '/configs/application.ini'));
$writer->write();
The application.ini lines become
resources.session.use_only_cookies = "1" //double quote appears T_T
resources.session.remember_me_seconds = "86400" //double quote appears T_T
What I want is the integer value must still remain the same (without double quotes).
Anyone can help me to solve this problem?
Thank you very much in advance
As Phil-Brown notes, when reading an ini file in PHP using parse_ini_file(), you always get strings back. Also, for for any value that isn't alphanumeric characters only, you should encase in double quotes, so Zend_Config_Writer encases all values.
Anyway,
In my solution, I had to remove some lines of code in Zend. The file that I changed was \Zend\Config\Writer\Ini.php for method _prepareValue() in line 150 to be like below
protected function _prepareValue($value)
{
/*
I comment it
if (is_integer($value) || is_float($value)) {
return $value;
} elseif (is_bool($value)) {
return ($value ? 'true' : 'false');
} else {
return '"' . addslashes($value) . '"';
}*/
return $value; // my line
}
just comment the original code of Zend and just pass and return $value.
So, by changing this file I never get any double quote anymore for string, boolean or even number. This is that what I want. :)
Thank you everyone.