string min,max length function - php

I'm trying to check min and max length of strings:
If I pass it an array, such as follows, I want the values to be returned if true and NULL if false:
$lenghts = array('a' => array('min' => 20, 'max' => 70),
'b' => array('min' => 50, 'max' => 800),
'c' => array('min' => 3, 'max' =>8));
And the values are:
$values = array('thread_title' => 'this is it', 'thread_content' => 'this is not it', 'thread_tags' => 'also not it')
;
EDIT
It's like 5am here (really quite sleepy), I should copied and pasted the correct version, sorry:
function string_min_max($string_array, $array)
{
$returns = array(); # store returned values
foreach ($array as $key)
{
# check for minimum:
if (array_key_exists('min', $key))
{
$minimum = (strlen($string_array[$key]) < $key['min'] ? $key = NULL : $key);
}
if (array_key_exists('max', $key))
{
$maximum = (strlen($string_array($key)) > $key['max'] ? $key = NULL : $key);
}
if ($minimum !== NULL && $maximum !== NULL)
{
$returns[$key]['min'] = $minimum;
$returns[$key]['max'] = $maximum;
}
}
}
This does not work:
string_min_max($values, $lengths);

This code is reducable to:
function string_min_max($array)
{
$returns = array(); # store returned values
foreach ($array as $key)
{
# check for minimum:
if (TRUE)
{
$minimum = (FALSE ? $key = NULL : $key);
}
}
}
OR:
function string_min_max($array)
{
$returns = array(); # store returned values
foreach ($array as $key)
{
$minimum = $key;
}
}
OR:
function string_min_max($array)
{
$returns = array(); # store returned values
}
OR:
(void)
So the answer is: no. It won't work.

Without looking too much at the details, one obvious problem is that you are not returning anyting from your function; you are building an array but you don´t use it so it gets destroyed at the moment your function ends.
I think that at least you will need this at the end of your function:
return $returns;
} // end function
You can then call your function like:
$results = string_min_max($values, $lenghts);

if use this for validate string by length and chars :
function checkString($string, $regex, $minlenght = 3, $maxlenght = 20) {
if(preg_match($regex, $string) && strlen($string) >= $minlenght && strlen($string) <= $maxlenght) return true;
return false;
}

Related

php match variable names using wildcard

I need to check for the existence of a variable.
Variables are not necessarily created in order 1.2.3. They could be created 2.4.3.1. These are also not created at the same time on the same page. So I am just wanted to check for the existence of the variable.
$_SESSION['rule1']
$_SESSION['rule2']
$_SESSION['rule3']
$_SESSION['rule4']
<?
if(isset($_SESSION['rule'.*wildcard*'])) {
do something
}
?>
I'm not sure how to go about this. The answer probably lies in REGEX but I am horrible with REGEX.
If you don't know need to know which rule* key is in the session array, only if any of them are present, then you could try this:
<?php
function prefixExists(array $assoc_array, $prefix)
{
$length = strlen($prefix);
foreach ($assoc_array as $key => $unused)
{
if (strncmp($key, $prefix, $length) === 0) {
return true;
}
}
return false;
}
Testing as follows:
session_start();
var_dump(prefixExists($_SESSION, 'rule'));
$_SESSION['rule3'] = 'some value from form';
var_dump(prefixExists($_SESSION, 'rule'));
Gives output:
bool(false)
bool(true)
Here is another solution with the use of preg_match:
function arrayHasSimilarKey(array $array, $matchKey)
{
$pattern = '/' . str_replace('*', '.*', $matchKey) . '/i';
foreach ($array as $key => $value) { echo $key.PHP_EOL;
if (preg_match($pattern, $key)) {
return true;
}
}
return false;
}
$testArray = ['abc' => 1, 'test_1' => 1, 'test_2' => 1, 'test2_1' => 1, 'test3_2' => 1];
$tests = [
0 => arrayHasSimilarKey($testArray, 'test*'), // true
1 => arrayHasSimilarKey($testArray, 'test2*_2'), // false
2 => arrayHasSimilarKey($testArray, 'test3*'), // true
3 => arrayHasSimilarKey($testArray, 'test3*_1'), // false
4 => arrayHasSimilarKey($testArray, '*_2') // false
];
var_dump($tests);
In your case, $testArray would be $_SESSION

Recursive PHP Function

I am trying to solve this problem to learn logic formulations, but this one's really taken too much of my time already.
Rules are simple, No loops and no built in PHP functions (eg. print_r, is_array.. etc).
This is what I have come up with so far.
function displayArray(array $inputArray, $ctr = 0, $tempArray = array()) {
//check if array is equal to temparray
if($inputArray != $tempArray) {
// check if key is not empty and checks if they are not equal
if($inputArray[$ctr]) {
// set current $tempArray key equal to $inputArray's corresponding key
$tempArray[$ctr] = $inputArray[$ctr];
if($tempArray[$ctr] == $inputArray[$ctr]) {
echo $tempArray[$ctr];]
}
$ctr++;
displayArray($inputArray, $ctr);
}
}
}
This program outputs this:
blackgreen
The problem starts when it reaches the element that is an array
$array = array(
'black',
'green',
array(
'purple',
'orange'
)
);
displayArray($array);
Any tips?
This what the return value is supposed to be: blackgreenpurpleorange
This was fun. I decided to make it work with most data types while I was at it. Just don't throw it any objects or nulls and things should work.
No more # error suppression. Now returns the string instead of echoing it.
I realized too late that isset() is actually a language construct rather than a function, and went with a null termination strategy to determine the end of the arrays.
function concatinateRecursive($array, $i = 0) {
static $s = '';
static $depth = 0;
if ($i == 0) $depth++;
// We reached the end of this array.
if ($array === NULL) {
$depth--;
return true;
}
if ($array === array()) return false; // empty array
if ($array === '') return false; // empty string
if (
$array === (int)$array || // int
$array === (float)$array || // float
$array === true || // true
$array === false || // false
$array === "0" || // "0"
$array == "1" || // "1" "1.0" etc.
(float)$array > 1 || // > "1.0"
(int)$array !== 1 // string
)
{
$s .= "$array";
return false;
}
// Else we've got an array. Or at least something we can treat like one. I hope.
$array[] = NULL; // null terminate the array.
if (!concatinateRecursive($array[$i], 0, $s)) {
$depth--;
return concatinateRecursive($array, ++$i, $s);
}
if ($depth == 1) {
return $s;
}
}
$array = array(
'black',
'green',
array(
'purple',
'orange'
)
);
echo concatinateRecursive($array);
blackgreenpurpleorange
Live demo
What about this? You must check if it is array or not.
function display_array(&$array, $index=0) {
if (count($array)<=$index) return;
if (is_array($array[$index])) {
echo '[ ';
display_array($array[$index]);
echo '] ';
}
else
echo "'" . $array[$index] . "' ";
display_array($array, $index+1);
}
// Try:
// $a = ['black', 'green', ['purple', 'orange'], 'beer', ['purple', ['purple', 'orange']]];
// display_array($a);
// Output:
// 'black' 'green' [ 'purple' 'orange' ] 'beer' [ 'purple' [ 'purple' 'orange' ] ]
try this have to use some inbuilt function like isset and is_array but its a complete working recursive method without using loop.
function displayArray(array $inputArray, $ctr = 0) {
if(isset($inputArray[$ctr]))
{
if(is_array($inputArray[$ctr]))
{
return displayArray($inputArray[$ctr]);
}
else
{
echo $inputArray[$ctr];
}
}
else
{
return;
}
$ctr++;
displayArray($inputArray, $ctr);
}
$array = array(
'black',
'green',
array(
'purple',
'orange'
)
);
displayArray($array);
OUTPUT :
blackgreenpurpleorange
DEMO
complete answer
$myarray = array(
'black',
'green',
array(
'purple',
'orange'
)
);
function printAll($a) {
if (!is_array($a)) {
echo $a, ' ';
return;
}
foreach($a as $k => $value) {
if($k<10){
//printAll($k);
printAll($value);
}
}
}
printAll($myarray);

search a php array for partial string match [duplicate]

This question already has answers here:
Filter multidimensional array based on partial match of search value
(3 answers)
Native function to filter array by prefix
(6 answers)
Closed 1 year ago.
I have an array and I'd like to search for the string 'green'. So in this case it should return the $arr[2]
$arr = array(0 => 'blue', 1 => 'red', 2 => 'green string', 3 => 'red');
is there any predefined function like in_array() that does the job rather than looping through it and compare each values?
For a partial match you can iterate the array and use a string search function like strpos().
function array_search_partial($arr, $keyword) {
foreach($arr as $index => $string) {
if (strpos($string, $keyword) !== FALSE)
return $index;
}
}
For an exact match, use in_array()
in_array('green', $arr)
You can use preg_grep function of php. It's supported in PHP >= 4.0.5.
$array = array(0 => 'blue', 1 => 'red', 2 => 'green string', 3 => 'red');
$m_array = preg_grep('/^green\s.*/', $array);
$m_array contains matched elements of array.
There are several ways...
$arr = array(0 => 'blue', 1 => 'red', 2 => 'green string', 3 => 'red');
Search the array with a loop:
$results = array();
foreach ($arr as $value) {
if (strpos($value, 'green') !== false) { $results[] = $value; }
}
if( empty($results) ) { echo 'No matches found.'; }
else { echo "'green' was found in: " . implode('; ', $results); }
Use array_filter():
$results = array_filter($arr, function($value) {
return strpos($value, 'green') !== false;
});
In order to use Closures with other arguments there is the use-keyword. So you can abstract it and wrap it into a function:
function find_string_in_array ($arr, $string) {
return array_filter($arr, function($value) use ($string) {
return strpos($value, $string) !== false;
});
}
$results = find_string_in_array ($arr, 'green');
if( empty($results) ) { echo 'No matches found.'; }
else { echo "'green' was found in: " . implode('; ', $results); }
Here's a working example: http://codepad.viper-7.com/xZtnN7
PHP 5.3+
array_walk($arr, function($item, $key) {
if(strpos($item, 'green') !== false) {
echo 'Found in: ' . $item . ', with key: ' . $key;
}
});
for search with like as sql with '%needle%' you can try with
$input = preg_quote('gree', '~'); // don't forget to quote input string!
$data = array(
1 => 'orange',
2 => 'green string',
3 => 'green',
4 => 'red',
5 => 'black'
);
$result = preg_filter('~' . $input . '~', null, $data);
and result is
{
"2": " string",
"3": ""
}
function check($string)
{
foreach($arr as $a) {
if(strpos($a,$string) !== false) {
return true;
}
}
return false;
}
A quick search for a phrase in the entire array might be something like this:
if (preg_match("/search/is", var_export($arr, true))) {
// match
}
function findStr($arr, $str)
{
foreach ($arr as &$s)
{
if(strpos($s, $str) !== false)
return $s;
}
return "";
}
You can change the return value to the corresponding index number with a little modification if you want, but since you said "...return the $arr[2]" I wrote it to return the value instead.
In order to find out if UTF-8 case-insensitive substring is present in array, I found that this method would be much faster than using mb_strtolower or mb_convert_case:
Implode the array into a string: $imploded=implode(" ", $myarray);.
Convert imploded string to lowercase using custom function:
$lowercased_imploded = to_lower_case($imploded);
function to_lower_case($str)
{
$from_array=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","Ä","Ö","Ü","Õ","Ž","Š"];
$to_array=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","ä","ö","ü","õ","ž","š"];
foreach($from_array as $key=>$val){$str=str_replace($val, $to_array[$key], $str);}
return $str;
}
Search for match using ordinary strpos: if(strpos($lowercased_imploded, "substring_to_find")!==false){do something}
This is a function for normal or multidimensional arrays.
Case in-sensitive
Works for normal arrays and multidimentional
Works when finding full or partial stings
Here's the code (version 1):
function array_find($needle, array $haystack, $column = null) {
if(is_array($haystack[0]) === true) { // check for multidimentional array
foreach (array_column($haystack, $column) as $key => $value) {
if (strpos(strtolower($value), strtolower($needle)) !== false) {
return $key;
}
}
} else {
foreach ($haystack as $key => $value) { // for normal array
if (strpos(strtolower($value), strtolower($needle)) !== false) {
return $key;
}
}
}
return false;
}
Here is an example:
$multiArray = array(
0 => array(
'name' => 'kevin',
'hobbies' => 'Football / Cricket'),
1 => array(
'name' => 'tom',
'hobbies' => 'tennis'),
2 => array(
'name' => 'alex',
'hobbies' => 'Golf, Softball')
);
$singleArray = array(
0 => 'Tennis',
1 => 'Cricket',
);
echo "key is - ". array_find('cricket', $singleArray); // returns - key is - 1
echo "key is - ". array_find('cricket', $multiArray, 'hobbies'); // returns - key is - 0
For multidimensional arrays only - $column relates to the name of the key inside each array.
If the $needle appeared more than once, I suggest adding onto this to add each key to an array.
Here is an example if you are expecting multiple matches (version 2):
function array_find($needle, array $haystack, $column = null) {
$keyArray = array();
if(is_array($haystack[0]) === true) { // for multidimentional array
foreach (array_column($haystack, $column) as $key => $value) {
if (strpos(strtolower($value), strtolower($needle)) !== false) {
$keyArray[] = $key;
}
}
} else {
foreach ($haystack as $key => $value) { // for normal array
if (strpos(strtolower($value), strtolower($needle)) !== false) {
$keyArray[] = $key;
}
}
}
if(empty($keyArray)) {
return false;
}
if(count($keyArray) == 1) {
return $keyArray[0];
} else {
return $keyArray;
}
}
This returns the key if it has just one match, but if there are multiple matches for the $needle inside any of the $column's then it will return an array of the matching keys.
Hope this helps :)

unset inside eval not working

I'm trying to remove an item from an array based on string;
public function delete($path){
// a key path given
if(strpos($path, '.') !== false){
$parts = explode('.', $path);
$first_key = array_shift($parts);
$data = $this->get($path);
// first key doesn't exist
if($data === false)
return false;
$parts = implode('"]["', $parts);
if(eval('if(isset($data["'.$parts.'"])){ unset($data["'.$parts.'"]); return true; } return false;'))
return $this->set($first_key, $data);
}
// a single key given
if(isset($this->data[$path]){
unset($this->data[$path]);
return true;
}
return false;
}
And it only works for single keys. Apparently the eval doesn't modify $data for some reason.
delete('test') works, but delete('test.child') doesn't...
I don't see why you'd need eval() here. See the following to replace your eval() construct:
<?php
function removeFromArray(&$array, $path)
{
if (!is_array($path)) {
$path = explode('.', trim($path, '.'));
}
$current = &$array;
while ($path) {
$key = array_shift($path);
// isset() would fail on `$array[$key] === null`
if (!array_key_exists($key, $current)) {
// abort if the array element does not exist
return false;
}
if (!$path) {
// reached the last element
unset($current[$key]);
return true;
}
if (!is_array($current[$key])) {
// can't go deeper, so abort
return false;
}
// continue with next deeper element
$current = &$current[$key];
}
return false;
}
$data = array(
'a' => 1,
'b' => array(
'c' => 2,
'd' => 3,
'e' => array(
'f' => 4,
),
),
);
var_dump(
removeFromArray($data, 'b.e.f'),
$data,
removeFromArray($data, 'b.c'),
$data
);
function unset_multiple($arr = [], $keys = [], $limitKeys = 30){
if($keys && count($keys) <= $limitKeys && is_array($arr) && count($arr) > 0){
foreach($keys as $key){
$keys[$key] = null;
}
return array_diff_key($arr, $keys);
} else{
throw new Exception("Input array is invalid format or number of keys to remove too large");
}
}
Example called:
$arr = array("name" => "Vuong", "age" => 20, "address" => "Saigon");
$res = unset_multiple($arr, ["name", "age"]);
//Result: ["address" => "Saigon"]
Make sure $keys param has all available keys in $arr param (only two-dimensional arrays). Need to remember this function is a helper to quickly removing multiple elements of array, not a function returns the absolute accurate results for all cases.

generic function for extracting values from an array with one particular key in PHP

Is it possible in PHP to extract values from an array with a particular key path and return an array of those values? I'll explain with an example:
$user =
array (
array(
'id' => 1,
'email' =>'asd#example.com',
'project' => array ('project_id' => 222, 'project_name' => 'design')
),
array(
'id' => 2,
'email' =>'asd2#example.com',
'project' => array ('project_id' => 333, 'project_name' => 'design')
)
);
/** I have to write a function something like: */
$projectIds = extractValuesWithKey($user, array('project', 'project_id'));
print_r($projectIds);
Output:
Array(
[0] => 222,
[1] => 333
)
I would have gone for a different approach (not that there's anything wrong with the array-function-based answers) by using a recursive iterator to flatten the array which makes the key-path comparison fairly simple.
function extractValuesWithKey($array, $keys) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$keys_count = count($keys);
// No point going deeper than we have to!
$iterator->setMaxDepth($keys_count);
$result = array();
foreach ($iterator as $value) {
// Skip any level that can never match our keys
if ($iterator->getDepth() !== $keys_count) {
continue;
}
// Build key path to current item for comparison
$key_path = array();
for ($depth = 1; $depth <= $keys_count; $depth++) {
$key_path[] = $iterator->getSubIterator($depth)->key();
}
// If key paths match, add to results
if ($key_path === $keys) {
$result[] = $value;
}
}
return $result;
}
To make the whole thing more useful, you could even wrap the code into a custom FilterIterator rather than a basic function, but I guess that's probably a different question entirely.
Well, that's easier than you think.
function extractValuesWithKey($array, $parts) {
$return = array();
$rawParts = $parts;
foreach ($array as $value) {
$tmp = $value;
$found = true;
foreach ($parts as $key) {
if (!is_array($tmp) || !isset($tmp[$key])) {
$found = false;
continue;
} else {
$tmp = $tmp[$key];
}
}
if ($found) {
$return[] = $tmp;
}
}
return $return;
}
If the 'key path' isn't dynamic, you can do a one-liner with array_map:
$projectIds = array_map(function($arr) { return $arr['project']['project_id']; }, $user);
Alternatively, for dynamic paths:
function extractValuesWithKey($users, $path) {
return array_map(function($array) use ($path) {
array_walk($path, function($key) use (&$array) { $array = $array[$key]; });
return $array;
}, $users);
}
The closures/anonymous functions only work with PHP 5.3+, and I've no idea how this would compare performance-wise to a double foreach loop. Note also that there's no error checking to ensure that the path exists.
I also used a similiar function in one of my projects, maybe you find this useful:
function extractValuesWithKey($data, $path) {
if(!count($path)) return false;
$currentPathKey = $path[0];
if(isset($data[$currentPathKey])) {
$value = $data[$currentPathKey];
return is_array($value) ? extractValuesWithKey($value, array_slice($path, 1)) : $value;
}
else {
$tmp = array();
foreach($data as $key => $value) {
if(is_array($value)) $tmp[] = extractValuesWithKey($value, $path);
}
return $tmp;
}
}

Categories