I have got an array wich contains several strings like this:
array(133) {
[0]=>
array(1) {
["row"]=>
array(5) {
[0]=>
string(10) "testd ' /% ata"
[1]=>
string(14) "testdata 111"
[2]=>
string(17) "testdata 123"
[3]=>
string(0) ""
[4]=>
string(0) ""
}
}
[1]=>
array(1) {
["row"]=>
array(5) {
[0]=>
string(9) "198"
[1]=>
string(14) "testdata"
[2]=>
string(41) "testdat"
[3]=>
string(0) ""
[4]=>
string(0) ""
}
}
My question is how can I check the strings within the array on special chars? These special chars are causing a syntax error when importing into my DB.
I think i need to use something like this?
preg_replace('/[^a-zA-Z0-9_ -%][().][\/]/s', '', $String);
Can anyone help me on this one?
Allright nog i have created this piece of code:
// search for special chars in the import data and remove them
$illegal = "#$%^&*()+=-[]';,./{}|:<>?~";
foreach ($data_set as $data)
foreach ($data_set['data'] as $row) {
if(strpbrk($row, $illegal)) {
echo($row);
die();
}
else {
//not allowed ,escape or do what you want
echo("no characters found");
die();
}
var_dump($row);
die();
}
But this still gives an error:
A PHP Error was encountered
Severity: Warning
Message: strpbrk() expects parameter 1 to be string, array given
Filename: controllers/import.php
Line Number: 153
no characters found
You may have a look at strpbrk. It should solve your problem.
Example:
$tests = "testd ' /% ata";
);
$illegal = "#$%^&*()+=-[]';,./{}|:<>?~";
echo (false === strpbrk($test, $illegal)) ? 'Allowed' : "Contains special chars";
But i suggest to escape your strings before inserting to database,it's much safer.
foreach ($yourArray as $array)
foreach ($array['row'] as $row) {
if(strpbrk($row, $illegal)) {
//allowed ,insert to db
}
else {
//not allowed ,escape or do what you want
}
}
Related
I return this array of objects from an API call like so. Note that $result is an array of arrays with $result[data] holding todo list objects and result[success] holding status of API call:
array(9) { [0]=> object(stdClass)#3 (5) { ["todo_id"]=> string(10) "1480430478" ["title"]=> string(13) "Check Printer" ["description"]=> string(8)
"Room 233" ["due_date"]=> string(10) "11/29/2016" ["is_done"]=> string(4) "true" } [1]=> object(stdClass)#4 (5) { ["todo_id"]=> string(10) "148043046" ["title"]=> string(18) "Doctor Appointment" ["description"]=> string(7)
"#4pm. " ["due_date"]=> string(10) "11/30/2016" ["is_done"]=> string(4) "true" }
etc..
I sort the array with usort fine and then I want to resort on the "is_done" field and put them at bottom of todo list in date order. The php to do this is :
//Sort by is_done
foreach($result[data] as $arrayElement ) {
foreach($arrayElement as $valueKey => $value) {
if(($valueKey == 'is_done') && ($value == 'true')){
$temp = $arrayElement;
//delete this particular object from the $array
unset($result[data][$arrayElement]);
array_push($result[data], $temp);
}
}
}
The problem I am having is my completed items are now at the end of the array but they are also still in their original position. The unset is not working. I have tried all variations on referencing the $result[data] item to no avail. This is probably something simple but I need some help if possible. Googling and checking this site shows no examples of unset in this type of situation. Thanks in advance.
Update:
after applying colburton's solution the API is now returning this data structure:
object(stdClass)#3 (6) { ["2"]=> object(stdClass)#4 (5) { ["todo_id"]=> int(1480698596) ["title"]=> string(7) "Test #4" ["description"]=> string(4) "test" ["due_date"]=> string(10) "12/02/2016" ["is_done"]=> string(5) "false" } ["3"]=> object(stdClass)#5 (5) { ["todo_id"]=> string(10) "1480617975" ["title"]=> string(13) "Check Printer" ["description"]=> string(4)
"Test" ["due_date"]=> string(10) "12/06/2016" ["is_done"]=> string(5) "false" } ["5"]=> object(stdClass)#6 (5) { ["todo_id"]=> int(1481136023) ["title"]=> string(9) "Todo item" ["description"]=> string(7) "test123" ["due_date"]=> string(10) "01/19/2017" ["is_done"]=> string(5) "false" } etc...
At the end of the call i do a
//json_decode the result
$result = #json_decode($result);
//check if we're able to json_decode the result correctly
if ($result == false || isset($result->success) == false) {
throw new Exception('Request was not correct');
}
//if there was an error in the request, throw an exception
if ($result->success == false) {
throw new Exception($result['errormsg']);
}
//if everything went great, return the data
return $result->data;
}
and then in main program I reference $result as
$result = $todo_items[0];
And that is where fatal error occurs now.
Update II:
Wanted to add that you then need to reindex the array
$result['data'] = array_values($result['data']);
I read here that this is a bug in json_decode. Thanks for the help....
Please use quotes around your array indices. This unsets what you want:
foreach ($result['data'] as $idx => $arrayElement) {
foreach ($arrayElement as $valueKey => $value) {
if (($valueKey == 'is_done') && ($value == 'true')) {
$temp = $arrayElement;
//delete this particular object from the $array
array_push($result['data'], $temp);
unset($result['data'][$idx]);
}
}
}
Seems really easy, but I can't seem to figure it out...
I have a simple line that gets mysql results through wordpress like this:
$sql_results = $wpdb->get_results($sql_phrase);
Then I parse it as JSON and echo it: json_encode($sql_results);
However, I want to add other data before I parse it as JSON. But I'm not sure how.
$sql_results basically gets me a list of post ID's, title and category.
It looks like this in var_dump (this is just the first row):
array(1)
{
[0]=> object(stdClass)#2737 (7)
{
["ID"]=> string(4) "2700"
["post_title"]=> string(18) "The compact helmet"
["category"]=> string(5) "Other"
}
}
Now to start with something easy, I'd like all associative arrays inside the object to have the extra key-value. I tried the following but got an error:
500 Internal error.
foreach($sql_search as $key => $value)
{
$value['pic_img'] = "test";
$sql_search[$key]=$value;
}
$result=$sql_search;
$sql_results = array(1)
{
[0]=> object(stdClass)#2737 (7)
{
["ID"]=> string(4) "2700"
["post_title"]=> string(18) "The compact helmet"
["category"]=> string(5) "Other"
}
}
foreach($sql_results as $key=>$value)
{
$value->solution = 'good';
$sql_results[$key]=$value;
}
$result=$sql_results;
var_dump($result);
$test = array ( array("ID"=>"35", "name"=>"Peter", "age"=>"43"),
array("ID"=>"34", "name"=>"James", "age"=>"19"), array("ID"=>"31", "name"=>"Joe", "age"=>"40") );
foreach($test as $key=>$value)
{
$value['solution'] = 'good';
$test[$key]=$value;
}
$result=$test;
var_dump($result);
I have the following simple code which check if the password contains at least two lowercases.
preg_match("/^(?=.*[a-z].*[a-z])+$/")
But this gave me the following error message:
Compilation failed : nothing to repeat at offset 19.
I can't figure where I'm wrong
Later Edit
The following code which checks if i have at least two special characters works well:
preg_match("/^(?=.*[!##$%^&*].*[!##$%^&*])[a-zA-Z_!##%^&*]+$/")
Try this
<?php
preg_match("/^(.*[a-z].*[a-z].*)$/", "2313123g123123u123", $result);
var_dump($result);
preg_match("/^(.*[a-z].*[a-z].*)$/", "65665656s656565", $result);
var_dump($result);
?>
result
array(2) {
[0]=>
string(18) "2313123g123123u123"
[1]=>
string(18) "2313123g123123u123"
}
array(0) {
}
The (?= ) defines an assertion, you can not repeat an assertion. Did you mean to use (?: )?
$data = array('ab', '123a345b', '123');
foreach ($data as $subject) {
$found = preg_match("/^(?:.*[a-z].*[a-z])+$/", $subject, $match);
var_dump($found, $match);
}
Output:
int(1)
array(1) {
[0]=>
string(2) "ab"
}
int(1)
array(1) {
[0]=>
string(8) "123a345b"
}
int(0)
array(0) {
}
i have registry data in text as below:
/Classes/CLSID/AppID,SZ,{0010890e-8789-413c-adbc-48f5b511b3af},
/Classes/CLSID/InProcServer32,KEY,,2011-10-14 00:00:33
/Classes/CLSID/InProcServer32/,EXPAND_SZ,%SystemRoot%\x5Csystem32\x5CSHELL32.dll,
/Classes/CLSID/InProcServer32/ThreadingModel,SZ,Apartment,
/Classes/CLSID/,KEY,,2011-10-14 00:00:36
/Classes/CLSID/,SZ,,
/Classes/CLSID/InprocServer32,KEY,,2011-10-14 00:00:36
/Classes/CLSID/InprocServer32/,C:\x5CWINDOWS\x5Csystem32\x5Cmstime.dll,
then i do $registry = explode "\n" and create list of arrays below:
var_dump($registry);
[1]=> string(121) "/Classes/CLSID/AppID,SZ,{0010890e-8789-413c-adbc-48f5b511b3af},"
[2]=> string(139) "/Classes/CLSID/InProcServer32,KEY,,2011-10-14 00:00:33"
[3]=> string(89) "/Classes/CLSID/InProcServer32/,EXPAND_SZ,%SystemRoot%\x5Csystem32\x5CSHELL32.dll,"
[4]=> string(103) "/Classes/CLSID/InProcServer32/ThreadingModel,SZ,Apartment,"
[5]=> string(103) "/Classes/CLSID/,KEY,,2011-10-14 00:00:36"
[6]=> string(121) "/Classes/CLSID/,SZ,,"
[7]=> string(139) "/Classes/CLSID/InprocServer32,KEY,,2011-10-14 00:00:36"
[8]=> string(89) "/Classes/CLSID/InprocServer32/,C:\x5CWINDOWS\x5Csystem32\x5Cmstime.dll,"
i also have keywords in array form
var_dump($keywords);
[1]=> string(12) "Math.dll"
[2]=> string(12) "System.dll"
[3]=> string(12) "inetc.dll"
[4]=> string(12) "time.dll"
i want to show lines in $registry that consist string in $keywords, so i create 1 function below:
function separate($line) {
global $keywords;
foreach ($keywords as $data_filter) {
if (strpos($line, $data_filter) !== false) {
return true;
}
}
return false;
}
$separate = array_filter($registry, 'separate');
since in $keywords consists "time.dll" so the codes produce result as below:
var_dump($seperate);
[1]=> string(89) "/Classes/CLSID/InprocServer32/,C:\x5CWINDOWS\x5Csystem32\x5Cmstime.dll,"
in my case the result is not true because, mstime.dll != time.dll and the information is improper.
the output should be empty.
lets say i replace the "\x5C" as space, there is any function that can do the job? thank you in advance.
There's preg_match.
To go along with the array_filter way you have to do things:
function separate($line) {
global $keywords;
foreach ($keywords as $data_filter) {
// '.' means any character in regex, while '\.' means literal period
$data_filter = str_replace('.', '\.', $data_filter);
if (preg_match("/\\x5C{$data_filter}/", $line)) {
return true;
}
}
return false;
}
This would return false for
/Classes/CLSID/InprocServer32/,C:\x5CWINDOWS\x5Csystem32\x5Cmstime.dll,
but true for
/Classes/CLSID/InprocServer32/,C:\x5CWINDOWS\x5Csystem32\x5Ctime.dll,
If you're not familiar with Regular Expressions, they are awesome and powerful. You can customize mine as needed to suit your situation.
I have a problem with preg_match_all.
While preg_match does reply the whole match as the first element of the array, preg_match_all doesn't - the first array is empty.
At least with the pattern I chose (havn't tried others since it's the one I need) it doesn't work.
Here is my code:
preg_match_all("/<\?\?(\t| )?translate(\t| )?;(\t| )?(.*)(\t| )?\?\?>/U", $file, $translate_info);
The pattern itself is working and producing subpattern matches.
Updated according to new given details :
$file = '<?? translate ; foo bar??>';
$res = preg_match_all('/<\?\?(\t| )?translate(\t| )?;(\t| )?(.*)(\t| )?\?\?>/U', $file, $translate_info);
echo "res='$res'\n";
var_dump($translate_info);
Works for me, it gives :
res='1'
array(6) {
[0]=>
array(1) {
[0]=>
string(26) "<?? translate ; foo bar??>"
}
[1]=>
array(1) {
[0]=>
string(1) " "
}
[2]=>
array(1) {
[0]=>
string(1) " "
}
[3]=>
array(1) {
[0]=>
string(0) ""
}
[4]=>
array(1) {
[0]=>
string(8) " foo bar"
}
[5]=>
array(1) {
[0]=>
string(0) ""
}
}