Any one have the ultimate PHP function(s) to add/remove parameters from a query string?
It needs to handle all possible cases, Ive seen ones that handle some cases, but not all.
Some example cases:
http://mysite.com?param1=1¶m2=2
http://www.mysite.com/?param1[]=1¶m1[]=2
ftp://user:pass#mysite.com/files/uploads/?param1=1¶m2=2
/?param1=1¶m2=2
/page.html?param1=1
/dir/page.html?test=1&bla=2
/dir/page.html?param1=1#jump_to_bottom
It should ideally be something like:
function add_get_param($uri, $name, $value = null) { ... }
function remove_get_param($uri, $name) { ... }
Some example tests:
$var = add_get_param('http://mysite.com?param1=1¶m2=2', 'param3', 3);
// http://mysite.com?param1=1¶m2=2¶m3=3
and:
$var = add_get_param('/dir/page.html?param1=1¶m2=2#jump_to_bottom', 'param3');
// /dir/page.html?param1=1¶m2=2¶m3#jump_to_bottom
etc...
Alright, I wrote my own functions:
PHP: http://pastebin.org/170157
jQuery: http://pastebin.org/169981
try the built in http_build_query and parse_str functions, they use associative arrays in the same style as $_GET as intermediates, but seem to do what you want...
I don't know about the ultimate solution. But PHP has several very helpful native functions that making your own defined function about should be easy.
Check out: html_build_query(), parse_str(), and parse_url()
This is the sketch for the function you can start with:
function add_get_param($url, $param, $value)
{
$parts_url = parse_url($url);
parse_str($parts_url['query'], $parts_query);
$parts_query[$param] = $value;
return $parts_url['scheme'] . '://' . $parts_url['host'] . '/' . $parts_url['path'] . '?' . http_build_query($parts_query);
}
var_dump(add_get_param('http://mysite.com?param1=1¶m2=2', 'param3', 3));
UPD: since parse_str breaks the data (replaces dots with underscores) I don't think this sketch is useful.
Alright I wrote my own, based on zerkms's sketch
class URL {
public static function each_get($url, $each_callback = null, $last_callback = null) {
$url = parse_url($url);
$result = '';
if (isset($url['scheme'])) $result .= $url['scheme'].'://';
if (isset($url['user'])) {
$result .= $url['user'];
if (isset($url['pass'])) $result .= ':'.$url['pass'];
$result .= '#';
}
if (isset($url['host'])) $result .= $url['host'];
if (isset($url['path'])) $result .= $url['path'];
if (!isset($url['query'])) $url['query'] = '';
$query = array();
$callable = is_callable($each_callback);
foreach (explode('&', $url['query']) as $param) {
if ($param == '') {
continue;
}
if (!$callable) {
$query[] = $param;
continue;
}
$callback_result = $each_callback($param);
if ($callback_result === true) {
$query[] = $param;
} elseif ($callback_result !== false) {
$query[] = $callback_result;
}
}
if (is_callable($last_callback)) {
$query = $last_callback($query);
}
$query = implode('&', $query);
$result .= strlen($query) ? '?'.$query : '';
if (isset($url['fragment'])) $result .= '#'.$url['fragment'];
return $result;
}
public static function add_get($url, $new_param, $new_value = null) {
return
static::each_get($url, function($param) {
$param = explode('=', $param);
if (isset($param[1])) {
return $param[0].'='.$param[1];
}
return $param[0];
}, function($query) use($new_param, $new_value) {
if ($new_value === null) {
$query[] = $new_param;
} else {
$query[] = $new_param.'='.$new_value;
}
return $query;
});
}
public static function remove_get($url, $remove_param) {
return
static::each_get($url, function($param) use($remove_param) {
$param = explode('=', $param);
return $param[0] != $remove_param;
});
}
public static function replace_get($url, $name, $value = null) {
return static::add_get(static::remove_get($url, $name), $name, $value);
}
}
And here is my limited test cases:
function test($test, $result) {
static $i;
$i++;
if ($test !== $result) {
echo $i.' Fail: got '.$test.' should be '.PHP_EOL.' '.$result.'<br>'.PHP_EOL;
} else {
echo $i.' Pass: '.$test.'<br>'.PHP_EOL;
}
}
$urls = array(
0 => 'http://user:pass#www.site.com?a=1',
1 => 'http://www.site.com?a=1',
2 => '/dir/page.php?a=1',
3 => '/dir/?a=1',
4 => '/dir?a=1',
5 => '/?a=1',
6 => '?a=1',
7 => 'http://user:pass#www.site.com?a=1#hash',
8 => 'http://www.site.com?a=1#hash',
9 => '/dir/page.php?a=1#hash',
10 => '/dir/?a=1#hash',
11 => '/dir?a=1#hash',
12 => '/?a=1#hash',
13 => '?a=1#hash',
14 => 'http://www.site.com/?a=1',
15 => 'http://www.site.com/?a=1#hash',
16 => '/dir/page.php?a=1&b=2&c=3',
);
test(URL::add_get($urls[0], 'b', 2), 'http://user:pass#www.site.com?a=1&b=2');
test(URL::add_get($urls[1], 'b', 2), 'http://www.site.com?a=1&b=2');
test(URL::add_get($urls[2], 'b', 2), '/dir/page.php?a=1&b=2');
test(URL::add_get($urls[3], 'b', 2), '/dir/?a=1&b=2');
test(URL::add_get($urls[4], 'b', 2), '/dir?a=1&b=2');
test(URL::add_get($urls[5], 'b', 2), '/?a=1&b=2');
test(URL::add_get($urls[6], 'b', 2), '?a=1&b=2');
test(URL::add_get($urls[7], 'b', 2), 'http://user:pass#www.site.com?a=1&b=2#hash');
test(URL::add_get($urls[8], 'b', 2), 'http://www.site.com?a=1&b=2#hash');
test(URL::add_get($urls[9], 'b', 2), '/dir/page.php?a=1&b=2#hash');
test(URL::add_get($urls[10], 'b'), '/dir/?a=1&b#hash');
test(URL::add_get($urls[11], 'berLongBla 1235_+'), '/dir?a=1&berLongBla 1235_+#hash');
test(URL::add_get($urls[12], 'a', 2), '/?a=1&a=2#hash');
test(URL::add_get($urls[13], 'a[]', 2), '?a=1&a[]=2#hash');
test(URL::add_get($urls[14], 'b', 2), 'http://www.site.com/?a=1&b=2');
test(URL::add_get($urls[15], 'b', 2), 'http://www.site.com/?a=1&b=2#hash');
test(URL::remove_get($urls[0], 'a'), 'http://user:pass#www.site.com');
test(URL::remove_get($urls[1], 'a'), 'http://www.site.com');
test(URL::remove_get($urls[2], 'a'), '/dir/page.php');
test(URL::remove_get($urls[3], 'a'), '/dir/');
test(URL::remove_get($urls[4], 'a'), '/dir');
test(URL::remove_get($urls[5], 'a'), '/');
test(URL::remove_get($urls[6], 'a'), '');
test(URL::remove_get($urls[16], 'b'), '/dir/page.php?a=1&c=3');
I also converted it to JavaScript/jQuery
URL = {};
URL.parse_url = function(str, component) {
var o = {
strictMode: false,
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:#]*):?([^:#]*))?#)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:#]+:[^:#\/]*#)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:#]*):?([^:#]*))?#)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-protocol to catch file:/// (should restrict this)
}
};
var m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) {uri[o.key[i]] = m[i] || "";}
switch (component) {
case 'PHP_URL_SCHEME':
return uri.protocol;
case 'PHP_URL_HOST':
return uri.host;
case 'PHP_URL_PORT':
return uri.port;
case 'PHP_URL_USER':
return uri.user;
case 'PHP_URL_PASS':
return uri.password;
case 'PHP_URL_PATH':
return uri.path;
case 'PHP_URL_QUERY':
return uri.query;
case 'PHP_URL_FRAGMENT':
return uri.anchor;
default:
var retArr = {};
if (uri.protocol !== '') {retArr.scheme=uri.protocol;}
if (uri.host !== '') {retArr.host=uri.host;}
if (uri.port !== '') {retArr.port=uri.port;}
if (uri.user !== '') {retArr.user=uri.user;}
if (uri.password !== '') {retArr.pass=uri.password;}
if (uri.path !== '') {retArr.path=uri.path;}
if (uri.query !== '') {retArr.query=uri.query;}
if (uri.anchor !== '') {retArr.fragment=uri.anchor;}
return retArr;
}
}
URL.each_get = function(url, each_callback, last_callback) {
url = URL.parse_url(url);
var result = '';
if (url.scheme) result += url.scheme+'://';
if (url.user) {
result += url.user;
if (url.pass) result += ':'+url.pass;
result += '#';
}
if (url.host) result += url.host;
if (url.path) result += url.path;
if (!url.query) url.query = '';
var query = [];
$.each(url.query.split('&'), function(key, param) {
if (param == '') {
return;
}
if (!each_callback) {
query.push(param);
return;
}
var callback_result = each_callback(param);
if (callback_result === true) {
query.push(param);
} else if (callback_result !== false) {
query.push(callback_result);
}
});
if (last_callback) {
query = last_callback(query);
}
query = query.join('&');
result += query.length ? '?'+query : '';
if (url.fragment) result += '#'+url.fragment;
return result;
}
URL.add_get = function(url, new_param, new_value) {
return URL.each_get(url, function(param) {
param = param.split('=');
if (typeof param[1] != 'undefined') {
return param[0]+'='+param[1];
}
return param[0];
}, function(query) {
if (typeof new_value == 'undefined') {
query.push(new_param);
} else {
query.push(new_param+'='+new_value);
}
return query;
});
}
URL.remove_get = function(url, remove_param) {
return URL.each_get(url, function(param) {
param = param.split('=');
return param[0] != remove_param;
});
}
URL.replace_get = function(url, name, value) {
return URL.add_get(URL.remove_get(url, name), name, value);
}
var i = 0;
function test(test, result) {
i++;
if (test !== result) {
console.debug(i+' Fail: got '+test+' should be '+result);
} else {
console.debug(i+' Pass: '+test);
}
}
And the limited text cases:
var urls = {
0 : 'http://user:pass#www.site.com?a=1',
1 : 'http://www.site.com?a=1',
2 : '/dir/page.php?a=1',
3 : '/dir/?a=1',
4 : '/dir?a=1',
5 : '/?a=1',
6 : '?a=1',
7 : 'http://user:pass#www.site.com?a=1#hash',
8 : 'http://www.site.com?a=1#hash',
9 : '/dir/page.php?a=1#hash',
10 : '/dir/?a=1#hash',
11 : '/dir?a=1#hash',
12 : '/?a=1#hash',
13 : '?a=1#hash',
14 : 'http://www.site.com/?a=1',
15 : 'http://www.site.com/?a=1#hash',
16 : '/dir/page.php?a=1&b=2&c=3'
};
test(URL.add_get(urls[0], 'b', 2), 'http://user:pass#www.site.com?a=1&b=2');
test(URL.add_get(urls[1], 'b', 2), 'http://www.site.com?a=1&b=2');
test(URL.add_get(urls[2], 'b', 2), '/dir/page.php?a=1&b=2');
test(URL.add_get(urls[3], 'b', 2), '/dir/?a=1&b=2');
test(URL.add_get(urls[4], 'b', 2), '/dir?a=1&b=2');
test(URL.add_get(urls[5], 'b', 2), '/?a=1&b=2');
test(URL.add_get(urls[6], 'b', 2), '?a=1&b=2');
test(URL.add_get(urls[7], 'b', 2), 'http://user:pass#www.site.com?a=1&b=2#hash');
test(URL.add_get(urls[8], 'b', 2), 'http://www.site.com?a=1&b=2#hash');
test(URL.add_get(urls[9], 'b', 2), '/dir/page.php?a=1&b=2#hash');
test(URL.add_get(urls[10], 'b'), '/dir/?a=1&b#hash');
test(URL.add_get(urls[11], 'berLongBla 1235_+'), '/dir?a=1&berLongBla 1235_+#hash');
test(URL.add_get(urls[12], 'a', 2), '/?a=1&a=2#hash');
test(URL.add_get(urls[13], 'a[]', 2), '?a=1&a[]=2#hash');
test(URL.add_get(urls[14], 'b', 2), 'http://www.site.com/?a=1&b=2');
test(URL.add_get(urls[15], 'b', 2), 'http://www.site.com/?a=1&b=2#hash');
Related
Sorry if this is a duplicate, I can't figure out what to search for to find the answer.
I have a foreach loop, and in that loop, I'm attempting to test if (A == B). Then once found I break the loop. If (A != B) in an iteration, I test if (X == Y).
My problem is that if (X == Y) is found to be true first, the loop breaks before if (A == B) can be tested.
Is there a better way to accomplish this task?
$variable[1] = ['A' => 'n', 'X' => 'n'];
$variable[2] = ['A' => 'n', 'X' => 'Y'];
$variable[3] = ['A' => 'B', 'X' => 'n'];
$test = 'B';
foreach ($variable as $value) {
if($value['A'] == $test || $value['X'] == "Y") {
echo 'The results: ' . $value['A'];
break;
}
}
// The results for $variable[2] are returned. I need the results for $variable[3] to be returned.
I did have an else statement which worked fine, but I was having to duplicate the output.
Thanks in advance!
The code above is a simplified version of what I'm working on. Here's the code I'm working actually working on.
foreach ($product_xml->products->product_styles as $style => $attribute) {
if(isset($_GET['color']) && $attribute['color'] == $color_selected || $attribute['is_default'] == "1") {
foreach ($attribute as $value){
$imgURL = (string)$value['imgurl'];
$thumburl = (string)$value['thumburl'];
$thumburl_array[(string)$value['side']] = (string)$value['thumburl'];
if (in_array($imgURL, $values)){continue;}
else{
array_push($values, $imgURL);
$imgURL = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$imgURL );
$thumburl = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$thumburl );
$thumburl = str_replace("150.png","500.png",$thumburl );
echo '<img src="'.$imgURL.'" class="pic'.$counter.'" title="'.$value['name'].'">';
$counter++;
}
}
break;
}
}
Use a temporary variable and move the echo to after the foreach.
$variable[1] = ['A' => 'n', 'X' => 'n'];
$variable[2] = ['A' => 'n', 'X' => 'Y'];
$variable[3] = ['A' => 'B', 'X' => 'n'];
$test = 'B';
$output = null;
foreach ($variable as $value) {
if($value['A'] == $test) {
$output = $value['A'];
break;
} else if ($output == null && $value['X'] == "Y") {
$output = $value['X'];
}
}
echo 'The results: ' . $output;
Here is my approximation with a function:
function search($variable, $test){
$alternative = null;
foreach($variable as $value){
if($value['A'] == $test){
return $value['A'];
}
if($value['X'] == 'Y' && $alternative === null){
$alternative = $value['A'];
}
}
return $alternative;
}
It will return first coincidence on A and if not found, first coincidence on X.
This way you only loop through foreach once.
Instead of looping you can use array_column to isolate one column of the array A or X.
Then use in_array to see if you find the $test in the array.
$test = 'B';
$test2 = 'Y';
If(in_array($test, array_column($variable, "A"))){
Echo $test . " Found in A";
}Else if(in_array($test2, array_column($variable, "X"))){
Echo $test2 . " Found in B";
}else{
Echo "none found";
}
https://3v4l.org/dv7Yp
Based off of the response from James Lalor I've come to this solution. If anyone sees a better/more optimal way of handling this, I'd love to hear!
$counter = 1;
$values = array();
$thumburl_array = array();
$found = false;
$find_default = false;
$style_count = count($product_xml->products->product_styles);
for ($i=0; $i < $style_count; $i++) {
if (isset($_GET['color']) && $product_xml->products->product_styles[$i]['color'] == $color_selected) {
$found = true;
} elseif (!$found && !$find_default && $i == $style_count - 1) {
$find_default = true;
$i = 0;
}
if ($find_default && $product_xml->products->product_styles[$i]['is_default'] == '1') {
$found = true;
}
if ($found) {
foreach ($product_xml->products->product_styles[$i] as $value){
$imgURL = (string)$value['imgurl'];
$thumburl = (string)$value['thumburl'];
$thumburl_array[(string)$value['side']] = (string)$value['thumburl'];
if (in_array($imgURL, $values)){continue;}
else{
array_push($values, $imgURL);
$imgURL = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$imgURL );
$thumburl = str_replace("REPLACE_DOMAIN_WITH",IDEQ_INKSOFTAPI_URL_SECURE,$thumburl );
$thumburl = str_replace("150.png","500.png",$thumburl );
echo '<img src="'.$imgURL.'" class="pic'.$counter.'" title="'.$value['name'].'">';
$counter++;
}
}
break;
}
}
Simplified version
$variable[] = ['A' => 'n', 'X' => 'n', 'result' => 'do'];
$variable[] = ['A' => 'n', 'X' => 'Y', 'result' => 're'];
$variable[] = ['A' => 'B', 'X' => 'n', 'result' => 'mi'];
$found = false;
$find_default = false;
$count = count($variable);
$test = 'B';
for ($i=0; $i < $count; $i++) {
if ($variable[$i]['A'] == $test) {
$found = true;
} elseif (!$found && !$find_default && $i == $count - 1) {
$find_default = true;
$i = 0;
continue;
}
if ($find_default && $variable[$i]['X'] == 'Y') {
$found = true;
}
if ($found) {
echo "Resulsts: " . $variable[$i]['result'];
break;
}
}
Thank you all for your feedback, much appreciated. Cheers.
I am creating my own custom cookie class and I can not seem to figure out what I am doing wrong. Here is my cookie class:
<?php
class Cookie implements CookieHandlerInterface {
private $_domain;
private $_secure;
public function __construct(array $config = array()) {
$this->_domain = isset($config['domain']) ? $config['domain'] : 'localhost';
$this->_secure = isset($config['secure']) ? $config['secure'] : false;
}
public function set($name, $value = null, $timeLength) {
if (!is_null($value)) {
if (is_array($value)) {
if ($this->__isMultiArray($array)) {
return null;
} else {
$value = $this->__arrayBuild($value);
$value = 'array(' . $value . ')';
}
} elseif (is_bool($value)) {
if ($value) {
$value = 'bool(true)';
} else {
$value = 'bool(false)';
}
} elseif (is_int($value)) {
$value = 'int(' . strval($value) . ')';
} elseif (is_float($value)) {
$value = 'float(' . strval($value) . ')';
} elseif (is_string($value)) {
$value = 'string(' . $value . ')';
} else {
return null;
}
} else {
$value = 'null(null)';
}
setcookie($name, $value, (time() + $timeLength), '/', $this->_domain, $this->_secure, true);
}
public function get($name, $defualtOutput = null) {
if (isset($_COOKIE[$name])) {
$output = rtrim($_COOKIE[$name], ')');
$xr1 = mb_substr($output, 0, 1);
if (equals($xr1, 'a')) {
$output = ltrim($output, 'array(');
return $this->__arrayBreak($output);
}
if (equals($xr1, 'b')) {
$output = ltrim($output, 'bool(');
if (equals($output, 'true')) {
return true;
} else {
return false;
}
}
if (equals($xr1, 'i')) {
$output = ltrim($output, 'int(');
return (int) $output;
}
if (equals($xr1, 'f')) {
$output = ltrim($output, 'float(');
return (float) $output;
}
if (equals($xr1, 's')) {
$output = ltrim($output, 'string(');
return $output;
}
if (equals($output, 'null(null)')) {
return null;
}
}
if (
!is_array($defualtOutput)
&& !is_bool($defualtOutput)
&& !is_int($defualtOutput)
&& !is_float($defualtOutput)
&& !is_string($defualtOutput)
&& !is_null($defualtOutput)
) {
trigger_error(
'The $defualtOutput var needs to be only certain types of var types. Allowed (array, bool, int, float, string, null).',
E_USER_ERROR
);
}
return $defualtOutput;
}
public function delete($name) {
if (isset($_COOKIE[$name])) {
setcookie($name, '', time() - 3600, '/', $this->_domain, $this->_secure, true);
}
}
private function __arrayBuild($array) {
$out = '';
foreach ($array as $index => $data) {
$out .= ($data != '') ? $index . '=' . $data . '|' : '';
}
return rtrim($out, '|');
}
private function __arrayBreak($cookieString) {
$array = explode('|', $cookieString);
foreach ($array as $i => $stuff) {
$stuff = explode('=', $stuff);
$array[$stuff[0]] = $stuff[1];
unset($array[$i]);
}
return $array;
}
private function __isMultiArray($array) {
foreach ($array as $key => $value) {
if (is_array($value)) {
return true;
}
}
return false;
}
}
?>
I set a test cookie for example app('cookie')->set('test', 'hello', 0);
sure enough it created the cookie like expected. So the cookie reads string(hello)
When I try to echo it, it echos the default value instead of the actual variable, so app('cookie')->get('test', 'test'); returns test
The get function should check if the cookie exists with isset($_COOKIE[$cookieName]) and then it should trim the extra ) with rtrim($_COOKIE[$cookieName], ')') then it should grab the first character in the string with mb_substr($_COOKIE[$cookieName], 0, 1) the 0 starts at the beginning and the 1 grabs only the first character.
After it compares it with the default (a, b, i, f, s) for example if it starts with an s its a string by default, if it was i it was sent as an int by default, etc. etc.
If they all come up as false it checks to see if it was sent as null if so it return null else it returns the default value passed.
The equals function is the same as $var1 == $var2 it is timing attack safe.
so it keeps returning the default value which is null, any help would be helpful thanks in advance.
Lol i feel real stupid i put 0 as the third argument thinking it will tell the cookie to expire when the browser session closes, but it did (time() + 0) which does not equal 0. so as it was setting the cookie it expired upon creation. So i did time() - (time() * 2). i achieved the goal i wanted.
I have an array lets suppose
$myarr = array(
'1',
'2',
'3',
'4-7',
'9',
'10',
)
$search2 = '2';
$search5 = '5';
I want to check both these 2 variables inside my $myarr. The first one can be easily found by using in_array but the $search5 is there inside '4-7' but what will I do to find the value? I don't want 2 foreach because i know I can use explode and then compare the start and end value. Is there a single or double line function that could help me achieve what I need? Thanks
PHP code demo
<?php
ini_set("display_errors", 1);
$search=2;
$result=null;
$myarr = array(
'1',
'2',
'3',
'4-7',
'9',
'10',
);
echo search_in_array($myarr,$search);
function search_in_array($myarr,$search)
{
$result=false;
array_map(function($number) use ($myarr,$search, &$result){
if(preg_match("/^(\d+)\-(\d+)$/", $number,$matches))
{
if(in_array($search,range($matches[1],$matches[2])))
{
$result= true;
}
}
elseif(preg_match("/^(\d+)$/", $number,$matches))
{
if(in_array($search,$myarr))
{
$result= true;
}
}
}, $myarr);
return $result;
}
Just as another answer:
$myarr = [
'1',
'2',
'3',
'4-7',
'9',
'10',
];
$search2 = '2';
$search5 = '5';
$search12 = '12';
function myInArray($needle, $haystack) {
return in_array(
$needle,
array_reduce(
$haystack,
function($incrementor, $value) {
return array_merge($incrementor, (strpos($value, '-') !== false) ? range(...explode('-', $value)) : [(int)$value]);
},
[]
)
);
}
foreach([$search2, $search5, $search12] as $searchValue) {
echo $searchValue, " is ",(myInArray($searchValue, $myarr) ? '' : 'NOT '), "in the array", PHP_EOL;
}
Probably not as efficient, especially when working with larger ranges of values in $myarr, but a slightly different approach
Demo
Here is almost one-liner,
$search = '5';
$matches = explode('-',array_values(preg_grep('/[-]/', $myarr))[0]);
if(in_array($search, $myarr)|| in_array($search,range($matches[0],$matches[1]))){
echo "found";
}else{
echo "not found";
}
I am exploding by - and then creating range with that and checking that with in_array.
Here is working DEMO
<?php
$myarr = ['1', '2', '3', '4-7', '9', '10'];
$search_array = [2, 5];
$search_results = [];
for ($i = 0; $i < count($search_array); $i++) {
$search_results[$search_array[$i]] = array_search($search_array[$i], $myarr);
if (!$search_results[$search_array[$i]]) {
foreach ($myarr as $value) {
if (strpos($value, "-") !== false) {
$data = explode("-", $value);
if ($search_array[$i] >= $data[0] && $search_array[$i] <= $data[1]) {
$search_results[$search_array[$i]] = array_search($value, $myarr);
}
}
}
}
if (!$search_results[$search_array[$i]]) {
unset($search_results[$search_array[$i]]);
}
}
var_dump($search_results);
Obviously using single foreach i cam up with this code to find ... set of data another is for loop not foreach.
#Ali Zia you can also try this logic like below:
<?php
$myarr = array(
'1',
'2',
'3',
'4-7',
'9',
'10',
);
$flag = 0;
$search = '5';
foreach($myarr as $value){
if($value == $search){
$flag = 1;
break;
}
else if(strpos($value, "-")){
$numberRange = explode("-", $value);
if($numberRange[0] <= $search && $numberRange[1] >= $search){
$flag = 1;
break;
}
}
}
if($flag == 1){
echo "yes number found in the array";
}
else{
echo "sorry not found";
}
Just for the sake of using range() and argument unpacking, because none of the other answers do:
function in_array_range($needle, array $haystack) {
if (in_array((int) $needle, $haystack, true)) {
return true;
}
$haystack = array_map(
function($element) {
return strpos($element, '-')
? range(... explode('-', $element, 2))
: (int) $element;
},
$haystack
);
foreach ($haystack as $element) {
if (is_array($element) && in_array((int) $needle, $element, true)) {
return true;
}
}
return false;
}
The function below returns the index of $needle in $haystack or -1 if no such element has been found.
function find(array $haystack, $needle) {
for ($i = 0; $i < count($haystack); $i++) {
$parts = explode("-", $haystack[$i]);
if (count($parts) == 2) {
if ($needle >= $parts[0] && $needle <= $parts[1]) {
return $i;
}
}
else if ($needle == $parts[0]) {
return $i;
}
}
return -1;
}
The function assumes that $array only contains a single non-negative integer or two non-negative integers separated by a dash.
You can now collect the indices like this:
$indices = array();
foreach ($searchValues as $searchValue) {
$indices[] = find($myarr, $searchValue);
}
Try with following code :
$myarr = array('1','2','3','4-7','9','10');
$search = 1; // Try with 5
$flag1 = false;
foreach($myarr as $number){
if(!is_numeric($number)){
list($start,$end) = explode("-",$number);
if($search >=$start && $search <=$end ){
echo $search .' Found';
}
}else if($flag1 == false){
if(in_array($search,$myarr)){
echo $search .' Found';
$flag1 = true;
}
}
}
Working Demo
I know the answer has already been accepted but here is my approach w/ and w/o using foreach.
(See demo).
With foreach :
<?php
$value = 3;
foreach($myarr as $myval){
list($start, $end) = strpos($myval, '-') ? explode('-', $myval) : [$myval, $myval];
if($value >= $start && $value <= $end){
echo $value . ' found between "' . $start . '" & "' . $end . '" !' . "\n";
}
}
Without foreach, "one line" code :
<?php
$value = 5;
$trueValues = [1,5];
$falseValues = [5, 7, 8];
var_dump(!count(array_diff($trueValues,array_reduce($myarr,function($arr, $item){return $arr + (strpos($item, '-') ? range(...explode('-', $item)) : [$item]);},[]))));
var_dump(!count(array_diff($falseValues,array_reduce($myarr,function($arr, $item){return $arr + (strpos($item, '-') ? range(...explode('-', $item)) : [$item]);},[]))));
var_dump(in_array($value, array_reduce($myarr, function($arr, $item){return $arr + (strpos($item, '-') ? range(...explode('-', $item)) : [$item]);}, array())));
Unfolded :
<?php
var_dump(
!count(
array_diff(
$trueValues,
array_reduce(
$myarr,
function($arr, $item){
return $arr + (strpos($item, '-') ? range(...explode('-', $item)) : [$item]);
},
[]
)
)
)
);
EDIT : Didn't know the ellipsis operator, thank you #Mark Baker
I have the following array:
$check = array(
$_POST["list1"],
$_POST["list2"],
$_POST["list3"],
$_POST["list4"],
$_POST["list5"],
$_POST["list6"],
$_POST["list7"],
$_POST["list8"],
$_POST["list9"],
$_POST["list10"],
);
I want to check if in this array all the values are unique (0 is the only value that can repeat).
So:
1, 2, 5, 7, 7, 0, 0, 4, 2, 1 -> wrong
1, 2, 3, 0, 0, 0, 0, 7, 8, 9 -> ok
Any idea?
PHP5.3
$result = array_reduce ($check, function ($valid, $value) {
static $found = array();
if (!$valid || (($value != 0) && in_array($value, $found))) {
return false;
} else {
$found[] = $value;
return true;
}
}, true);
Or
$counted = array_count_values($check);
unset($counted[0], $counted['0']); // Ignore "0" (dont know, if its an integer or string)
$valid = (count($counted) == array_sum($counted));
<?php
function isValidArray($array)
{
$found = array();
foreach($array as $item)
{
$item = (int) $item;
if($item == 0)
continue;
if(in_array($item, $found))
return false;
array_push($found, $item);
}
return true;
}
?>
I have a $data at a column1 shows me:
"AAA123"
"ABC1234"
"ABD123"
"BAC12"
"CAB123"
"DA125"
and so on..
I would like to show $data starting with only "AB" which shows me at column1 like :
"ABC1234"
"ABD123"
not the others but also other rows and columns related to "ABC1234" and "ABD123"
Thanx in advance.
Sample structure http://img706.imageshack.us/img706/8994/34310422.jpg
If $data is an array of strings, you can use array_filter.
PHP 5.3 or later:
$AB = array_filter($data, function($str) {
return 'AB' == substr($str, 0, 2);
});
before PHP 5.3:
$AB = array_filter($data,
create_function('$str',
'return "AB" == substr($str, 0, 2);'
) );
Or:
function create_prefix_tester($prefix) {
return create_function('$str',
"return '$prefix' == substr(\$str, 0, " . strlen($prefix) . ');'
);
}
$AB = array_filter($data, create_prefix_tester('AB'));
Or you could use a loop:
foreach ($data as $str) {
if ('AB' == substr($str, 0, 2)) {
// do stuff
...
}
}
Edit
From the sample code, it looks like you'll want the loop:
while (FALSE !== ($line = fgets($fp))) {
$row = explode('|', $line); // split() is deprecated
if ('AB' == substr($row[0], 0, 2)) {
switch($sortby) {
case 'schools': // fallthru
default:
$sortValue = $row[0];
break;
case 'dates':
$sortValue = $row[1];
break;
case 'times':
$sortValue = $row[2];
break;
}
array_unshift($row, $sortValue);
$table[] = $row;
}
}
or:
function cmp_schools($a, $b) {
return strcmp($a[0], $b[0]);
}
function cmp_dates($a, $b) {
return $a['datestamp'] - $b['datestamp'];
}
function cmp_times($a, $b) {
return $a['timestamp'] - $b['timestamp'];
}
while (FALSE !== ($line = fgets($fp))) {
$row = explode('|', $line); // split() is deprecated
if ('AB' == substr($row[0], 0, 2)) {
$when = strtotime($row[1] + ' ' + $row[2]);
$row['timestamp'] = $when % (60*60*24);
$row['datestamp'] = $when - $row['timestamp'];
$table[] = $row;
}
}
usort($table, 'cmp_' + $sortby);
I would simply use substr(), as in the following snippet:
if (substr($str, 0, 2) == 'AB') {
// The string is right.
}
Use strpos (http://www.php.net/manual/en/function.strpos.php), like
if (strpos($my_string, "AB") === 0) {
<do stuff>
}
Be very sure to use === instead of ==, because if "AB" is not found then the function will return false, which will equate to 0 using ==.