in_array function, why this doesn't work? - php

I'm trying to validate a string to an array of numbers. If the string only contains numbers then the function should validate, but in_array isn't working, any suggestions?
$list = array(0,1,2,3,4,5,6,7,8,9);
$word = 'word';
$split = str_split($word);
foreach ($split as $s) {
if (!in_array($s, $list)) {
print 'asdf';
}
}
here is the class:
class Validate_Rule_Whitelist {
public function validate($data, $whitelist) {
if (!Validate_Rule_Type_Character::getInstance()->validate($data)) {
return false;
}
$invalids = array();
$data_array = str_split($data);
foreach ($data_array as $k => $char) {
if (!in_array($char, $whitelist)) {
$invalids[] = 'Invalid character at position '.$k.'.';
}
}
if (!empty($invalids)) {
$message = implode(' ', $invalids);
return $message;
}
return true;
}
}

in_array comparison with loosely typed values is somewhat strange. What would work in your case is:
$list = array('0','1','2','3','4','5','6','7','8','9');
$word = 'word';
$split = str_split($word);
foreach ($split as $s) {
if (!in_array($s, $list, true)) {
print 'asdf';
}
}
This compares strings with strings and results in no surprises.
But, as noted in the comments already, this is quite wrong way to do things and it is much better to use filter_var() or regular expressions** to achieve what you're trying.

it's ugly as sin but it works, no elegant solution here, just a double loop, if you see any problems please let me know
$match = array();
foreach ($data_array as $k => $char) {
foreach ($whitelist as $w) {
if (!isset($match[$k])) {
if ($char === $w) {
$match[$k] = true;
}
}
}
if (!isset($match[$k]) || $match[$k] !== true) {
$invalids[$k] = 'Invalid character at position '.$k.'.';
}
}

Something along the lines of this should work:
<?php
$validate_me = '123xyz';
if(preg_match("/[^0-9]/", $validate_me, $matches))
print "non-digit detected";
?>

update: add the $type = gettype ... settype($char, $type) to allow === to function correctly when checking for integers
foreach ($data_array as $k => $char) {
foreach ($whitelist as $w) {
if (!isset($match[$k])) {
$type = gettype($w);
if (gettype($char) !== $type) {
settype($char, $type);
}
if ($char === $w) {
$match[$k] = true;
}
}
}
...

Related

How to splitting words match by patterns with PHP

I have an array of words. e.g.,
$pattern = ['in', 'do', 'mie', 'indo'];
I wanna split a words match by the patterns to some ways.
input =
indomie
to output =
$ in, do, mie
$ indo, mie
any suggests?
*ps sorry for bad english. thank you very much!
it was an very interesting question.
Input:-
$inputSting = "indomie";
$pattern = ['in', 'do', 'mie', 'indo','dom','ie','indomi','e'];
Output:-
in,do,mie
in,dom,ie
indo,mie
indomi,e
Approach to this challenge
Get the pattern string length
Get the all the possible combination of matrix
Check whether the pattern matching.
if i understand your question correctly then above #V. Prince answer will work only for finding max two pattern.
function sampling($chars, $size, $combinations = array()) {
if (empty($combinations)) {
$combinations = $chars;
}
if ($size == 1) {
return $combinations;
}
$new_combinations = array();
foreach ($combinations as $combination) {
foreach ($chars as $char) {
$new_combinations[] = $combination . $char;
}
}
return sampling($chars, $size - 1, $new_combinations);
}
function splitbyPattern($inputSting, $pattern)
{
$patternLength= array();
// Get the each pattern string Length
foreach ($pattern as $length) {
if (!in_array(strlen($length), $patternLength))
{
array_push($patternLength,strlen($length));
}
}
// Get all the matrix combination of pattern string length to check the probablbe match
$combination = sampling($patternLength, count($patternLength));
$MatchOutput=Array();
foreach ($combination as $comp) {
$intlen=0;
$MatchNotfound = true;
$value="";
// Loop Through the each probable combination
foreach (str_split($comp,1) as $length) {
if($intlen<=strlen($inputSting))
{
// Check whether the pattern existing
if(in_array(substr($inputSting,$intlen,$length),$pattern))
{
$value = $value.substr($inputSting,$intlen,$length).',';
}
else
{
$MatchNotfound = false;
break;
}
}
else
{
break;
}
$intlen = $intlen+$length;
}
if($MatchNotfound)
{
array_push($MatchOutput,substr($value,0,strlen($value)-1));
}
}
return array_unique($MatchOutput);
}
$inputSting = "indomie";
$pattern = ['in', 'do', 'mie', 'indo','dom','ie','indomi','e'];
$output = splitbyPattern($inputSting,$pattern);
foreach($output as $out)
{
echo $out."<br>";
}
?>
try this one..
and if this solves your concern. try to understand it.
Goodluck.
<?php
function splitString( $pattern, $string ){
$finalResult = $semiResult = $output = array();
$cnt = 0;
# first loop of patterns
foreach( $pattern as $key => $value ){
$cnt++;
if( strpos( $string, $value ) !== false ){
if( implode("",$output) != $string ){
$output[] = $value;
if( $cnt == count($pattern) ) $semiResult[] = implode( ",", $output );
}else{
$semiResult[] = implode( ",", $output );
$output = array();
$output[] = $value;
if( implode("",$output) != $string ){
$semiResult[] = implode( ",", $output );
}
}
}
}
# second loop of patterns
foreach( $semiResult as $key => $value ){
$stackString = explode(",", $value);
/* if value is not yet equal to given string loop the pattern again */
if( str_replace(",", "", $value) != $string ){
foreach( $pattern as $key => $value ){
if( !strpos(' '.implode("", $stackString), $value) ){
$stackString[] = $value;
}
}
if( implode("", $stackString) == $string ) $finalResult[] = implode(",", $stackString); # if result equal to given string
}else{
$finalResult[] = $value; # if value is already equal to given string
}
}
return $finalResult;
}
$pattern = array('in','do','mie','indo','mi','e', 'i');
$string = 'indomie';
var_dump( '<pre>',splitString( $pattern, $string ) );
?>

Find and extract words from strings

I need to find and extract words (array) in a string. I tried many techniques, and I found how to find first occurrences, but can't get it to work recursively.
$uda_state = [
"uda actif",
"uda stagiaire",
"stagiaire uda",
"uda",
"apprenti actra",
"actra apprenti",
"actra"
];
$arr = [
'<p>Nothing here</p>',
'<p>UDA Stagiaire et ACTRA</p>',
'<p>Stagiaire UDA</p>',
'<p>Should not pop</p>'
];
function contains($str, array $arr)
{
foreach($arr as $a) {
if ($pos = stripos($str,$a)) return true;
}
return false;
}
function extractWord($str, array $arr)
{
foreach($arr as $a) {
if ($pos = stripos($str, $a)) return $arr;
}
}
function find_uda_actra($str, array $arr = []) {
global $uda_state;
if (contains($str, $uda_state)) {
$word = extractWord($str, $uda_state);
$arr[] = $word;
$str = str_ireplace($word, '', $str);
if ($str != '') {
if (contains($str, $uda_state)) {
list($str, $arr) = find_uda_actra($str, $arr);
}
else {
return [$str, $arr];
}
} else {
return [$str, $arr];
}
}
return [$str, $arr];
}
foreach ($arr as $str) {
list($content, $uda) = find_uda_actra($str);
echo 'Content:'.PHP_EOL;
var_dump($content);
echo 'UDA:'.PHP_EOL;
var_dump($uda);
}
All I get now is emptied content and the whole $uda_state in each $uda. I need only the one that was found.
3v4l link for sandbox.

merge many array based on a common key php

I wasn't so clear in my first question, so i deleted it and here is a reformulation;
I have those arrays:
$open = array(array("FAI1","34"),array("FAI2","34"),array("FAI3","34"));
$click = array(array("FAI2","52"),array("FAI1","68"),array("FAI3","99"));
$unsubscribe = array(array("FAI2","103"),array("FAI3","67"),array("FAI1","102"));
$def_sent = array(array("FAI1","34",24),array("FAI2","34",23),array("FAI3","34",27));
$SB = array(array("FAI2","103"),array("FAI3","67"),array("FAI1","102"));
$HB = array(array("FAI2","103"),array("FAI3","67"),array("FAI1","102"));
I searched for a function to merge them and get a result like this:
$result = array(array("FAI1",34,68,102,34,24,102,102)
,array("FAI2","34",23.....),
array("FAI3","34",27....));
and to do this, i used the function, in the php online documentation, and this is the function
function array_merge_recursive() {
$arrays = func_get_args();
$base = array_shift($arrays);
foreach ($arrays as $array) {
reset($base);
while (list($key, $value) = #each($array)) {
if (is_array($value) && #is_array($base[$key])) {
$base[$key] = array_merge_recursive($base[$key], $value);
} else {
$base[$key] = $value;
}
}
}
return $base;
}
But instead of getting the result above i got this:
FAI1|34
FAI2|34
FAI3|34
FAI2|52
FAI1|68
FAI3|99
...
So i need some help to reformulate this function to get the expected result.
Try this function:
function array_merge_rec() {
$arrays = func_get_args();
$result = array();
foreach ($arrays as $arg) {
if (is_array($arg)) {
foreach ($arg as $item) {
if (!isset($result[$item[0]])) {
$result[$item[0]] = $item;
} else {
$result[$item[0]][] = $item[1];
}
}
} else {
echo "$arg skippend because it isn't array\n";
}
}
return array_values($result);
}
Does it help?

Comparing in_array values

I have a array of val which has dynamic strings with underscores. Plus I have a variable $key which contains an integer. I need to match $key with each $val (values before underscore).
I did the following way:
<?php
$key = 2; //always a dynamic number
$val = array('3_33', '2_55'); //always a dynamic string with underscore
if(in_array($key, $val)) {
echo 'Yes';
}
else
{
echo 'No';
}
?>
Though this code works fine, I want to know if its a correct way or suggest some better alternative.
use this function for regex match from php.net
function in_array_match($regex, $array) {
if (!is_array($array))
trigger_error('Argument 2 must be array');
foreach ($array as $v) {
$match = preg_match($regex, $v);
if ($match === 1) {
return true;
}
}
return false;
}
and then change your code to use this function like this:
$key = 2; //always a dynamic number
$val = array('3_33', '2_55'); //always a dynamic string with underscore
if(in_array_match($key."_*", $val)) {
echo 'Yes';
}
else
{
echo 'No';
}
This should work :
foreach( $val as $v )
{
if( strpos( $v , $key .'_' ) === true )
{
echo 'yes';
}
else {
echo 'no';
}
}
you can use this
function arraySearch($find_me,$array){
$array2 =array();
foreach ($array as $value) {
$val = explode('_',$value);
$array2[] =$val[0];
}
$Key = array_search($find_me, $array2);
$Zero = in_array($find_me, $array2);
if($Key == NULL && !$Zero){
return false;
}
return $Key;
}
$key = 2; //always a dynamic number
$val = array('3_33', '2_55'); //always a dynamic string with underscore
$inarray = false;
foreach($val as $v){
$arr = explode("_", $val);
$inarray = $inarray || $arr[0] == $key
}
echo $inarray?"Yes":"No";
The given format is quite unpractically.
$array2 = array_reduce ($array, function (array $result, $item) {
list($key, $value) = explode('_', $item);
$result[$key] = $value;
return $result;
}, array());
Now you can the existence of your key just with isset($array2[$myKey]);. I assume you will find this format later in your execution useful too.

Check if key exists in $_SESSION by building index string

I need to check if a key exists and return its value if it does.
Key can be an array with subkeys or endkey with a value.
$_SESSION['mainKey']['testkey'] = 'value';
var_dump(doesKeyExist('testkey'));
function doesKeyExist($where) {
$parts = explode('/',$where);
$str = '';
for($i = 0,$len = count($parts);$i<$len;$i++) {
$str .= '[\''. $parts[$i] .'\']';
}
$keycheck = '$_SESSION[\'mainKey\']' . $str;
if (isset(${$keycheck})) {
return ${$keycheck};
}
// isset($keycheck) = true, as its non-empty. actual content is not checked
// isset(${$keycheck}) = false, but should be true. ${$var} forces a evaluate content
// isset($_SESSION['mainKey']['testkey']) = true
}
Using PHP 5.3.3.
Instead of building the string, just check if the key exists within your loop.
For instance:
function doesKeyExist($where) {
$parts = explode('/',$where);
$currentPart = $_SESSION['mainKey'];
foreach($parts as $part) {
if (!isset($currentPart[$part])) {
return false;
}
$currentPart = $currentPart[$part];
}
return true;
}
function getByKeys($keys, $array) {
$value = $array;
foreach (explode('/', $keys) as $key) {
if (isset($value[$key])) {
$value = $value[$key];
} else {
return null;
}
}
return $value;
}
Perhaps I'm misunderstanding the question, but this would appear to be the simplest way of doing it:
function getKey($arr, $key) {
if (array_key_exists($key, $arr)) {
return $arr[$key];
} else {
return false;
}
}
$value = getKey($_SESSION['mainKey'], 'testkey');
You should use $$keycheck, not ${$keycheck}.
The last notation is only if you use the variable inside a string (e.g. "${$keycheck}")
See http://php.net/manual/en/language.variables.variable.php for more details about variable variables
You might want to use the eval() php function for this.
function doesKeyExist($where) {
$parts = explode('/',$where);
$str = '';
for($i = 0,$len = count($parts);$i<$len;$i++) {
$str .= '["'. $parts[$i] .'"]';
}
eval('$keycheck = $_SESSION["mainKey"]' . $str . ';');
if (isset($keycheck)) {
return $keycheck;
}
}
HTH

Categories