This code is properly working. However, I'm thinking of ways to shorten it since I'm still learning PHP. I'm using this snippet to generate a title for an e-mail I am going to send to somebody.
foreach($_POST as $key => $value) {
if(strpos($key,'cloud') !== false && !$a) {
$title .= "CS ";
$a = true;
}
if(strpos($key,'dco') !== false && !$b) {
$title .= "DC ";
$b = true;
}
if(strpos($key,'comm') !== false && !$c) {
$title .= "BC ";
$c = true;
}
if(strpos($key,'fiber') !== false && !$d) {
$title .= "FC ";
$d = true;
}
}
I'm pretty sure they do the same thing (all of the if statements). If there's anything you can suggest/advice, please let me know!
Cheers!
You can simple create function. This code should work:
foreach($_POST as $key => $value) {
checkstrpos($key,'cloud',$a,$title,"CS ");
checkstrpos($key,'dco',$b,$title,"DC ");
checkstrpos($key,'comm',$c,$title,"BC ");
checkstrpos($key,'fiber',$d,$title,"FC ");
}
function checkstrpos($key,$text, &$variable, &$title, $add) {
if(strpos($key,$text) !== false && !$variable) {
$title .= $add;
$variable = true;
}
}
Another solution without using references:
foreach($_POST as $key => $value) {
list($title, $a) = checkstrpos($key,'cloud',$a,$title,"CS ");
list($title, $b) = checkstrpos($key,'dco',$b,$title,"DC ");
list($title, $c) = checkstrpos($key,'comm',$c,$title,"BC ");
list($title, $d) = checkstrpos($key,'fiber',$d,$title,"FC ");
}
function checkstrpos($key,$text, $variable, $title, $add) {
if(strpos($key,$text) !== false && !$variable) {
$title .= $add;
$variable = true;
}
return array($title, $variable);
}
To me I think that code is simple enough.
If you're attempting to make the code shorter, you risk making it harder to read.
The one comment I have is don't use generic variable names like $a, $b, $c and $d. Use proper descriptive variable names instead.
It's possible that you could swap the positions of these conditions, that is, change
if(strpos($key,'dco') !== false && !$b)
to
if(!$b && strpos($key,'dco') !== false)
But this is more of a micro-optimization than a simplification or change in readability.
Another solution without using a function:
$infos = array(
array('cloud', 'CS', &$a),
array('dco', 'DC', &$b),
array('comm', 'BC', &$c),
array('fiber', 'FC', &$d)
);
foreach($_POST as $k => $v) {
foreach($infos as $info) {
if ( !$info[2] && strpos($k, $info[0]) !== false) {
$title .= $info[1]. ' ';
$info[2] = true;
}
}
}
This isn't the best way though. As suggested in another answer, it'd be better to use a function: an anonymous function (aka closure).
Related
Why do I always get a array with one item of empty string for an empty .csv file?
$content = file('products.csv');
print_r($content);
result:
Array ( [0] => )
Can I return false so that I know there is nothing in the csv file?
This seems like ad-hoc behaviour particular to your taste (no problem with that at all). Which means, you should probably create a wrapper function for this.
function contentIsNotEmpty($content) {
$isEmpty = empty($content) || (count($content) == 1 && empty($content[0]));
return $isEmpty ? false : $content;
}
EDIT: Incorporated #scrowler's feedback, and Michael J. Mulligan's.
A single line test should get you the result:
$empty = empty($content) || (count($content) === 1 && empty($content[0]));
The following should avoid the "fake empty":
$empty = empty($content) || (count($content) === 1 && $content[0] === '');
If you need a re-usable function, and prefer, as you stated, to get an array or nothing, this may be helpful:
function get_file($file_name = null, $strict = false) {
$return = null;
if(!empty($file_name) && is_readable($file_name)) {
$contents = file($file_name);
if(
!empty($contents)
&& (
count($contents) > 1
|| (
!empty($contents[0])
|| ($strict && $contents[0] !== '')
)
)
) {
$return = $contents;
}
}
return $return;
}
I mean, we could get all kinds of creative and iterate over lines, etc. But I think you get the idea.
If you want to get a CSV file, I would suggest using a method like fgetcsv() (repurposed):
function getcsv($file_name, $headers = array(), $delimiter = ',', $enclosure = '"', $escape = "\\" ) {
$contents = array();
$get_headers = $headers === FALSE;
$headers = is_array($headers) ? array_values($headers) : array();
if(!empty($file_name) && is_readable($file_name)) {
$row = 0;
if (($handle = fopen($file_name, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 0, $delimiter, $enclosure, $escape)) !== FALSE) {
if($get_headers && empty($headers)) {
$headers = $data;
continue;
}
foreach($data as $i => $col_value) {
$col_name = isset($headers[$i]) ? $headers[$i] : $i;
$contents[$row][$col_name] = $col_value;
}
$row++;
}
fclose($handle);
}
}
return $contents;
}
Note, above is not tested, just a quick draft, and I am going to bed. I'll edit it tomorrow if need be.
Finally, if you are getting a single line, with white-space, and this validates as "empty" in your eyes, simple test it after a trim:
$empty_line = trim($content[$line_num]) == '';
Not sure what else to tell you. I think we have equipped you with quite a few tools and ways to validate this situation. Best of luck.
try this
$content = file('products.csv');
if(!empty($content)){
print_r();}{
else{
// Do something if no content
}
I am developing a system that searches for words that the user types in php files, using PHP without MySQL but I am having a problem. The system works really well when there is not a line break in the file. For example, if I search for the word "good" in a file that contains the text "good morning" works fine, but if I search for "good" in a file that contains the text "goodmorning" (with a line break) it won't list the file as a result. Here is my code:
index.php
<form action="busca.php" method="get">
<input type="text" name="s"><br>
<input type="submit">
</form>
busca.php
<?php
$pesq = (isset($_GET['s'])) ? trim($_GET['s']) : '';
if (empty($pesq)) {
echo 'Type something.';
} else {
$index = "index.php";
$busca = glob("posts/content/*.php", GLOB_BRACE);
$lendo = "";
$conteudo = "";
foreach ($busca as $item) {
if ($item !== $index) {
$abrir = fopen($item, "r");
while (!feof($abrir)) {
$lendo = fgets($abrir);
$conteudo .= $lendo;
$lendo .= strip_tags($lendo);
}
if (stristr($lendo, $pesq) == true) {
$dados = str_replace(".php", "", $item);
$dados = basename($dados);
$result[] = "$dados";
unset($dados);
}
fclose($abrir);
}
}
if (isset($result) && count($result) > 0) {
$result = array_unique($result);
echo '<ul>';
foreach ($result as $link) {
echo "<li>$link</li>";
}
echo '</ul>';
} else {
echo 'No results';
}
}
?>
Your usage of stristr is incorrect.
Compare it with false like this:
if (stristr($lendo, $pesq) !== false) {
If a string is located — the function returns the substring. Which can be casted as boolean true or false, you never know. If it doesn't find it — it returns false — the only correct value you should compare it to.
Even better to use strpos for this.
My variant:
foreach ($busca as $item) {
if ($item !== $index) {
$lendo = file_get_contents($item);
$lendo = strip_tags($lendo);
if (strpos($lendo, $pesq) !== false) {
$dados = str_replace(".php", "", basename($item));
$result[] = "$dados";
}
}
}
To fix the linebreaks - try to get rid of them
Like this:
$lendo = file_get_contents($item);
$lendo = strip_tags($lendo);
$lendo = str_replace(["\r","\n"], ' ', $lendo);
//let my controller be C and method be:
function X($array){}
//And my url to call it is:
localhost/mysite/C/X/array
Well i tried it but it returns 400-Bad Request response.
Does anyone know how to do it? Quick response will help me a lot//Thanx
localhost/mysite/C/X/?array=1&&?array=2....
$array = $this->input->get('array');
or
localhost/mysite/C/X/1,2,3,4,5
$array = explode(',' $this->uri->segment(n));
// in app/config/config.php
$config['permitted_uri_chars'] = 'a-z 0-9~%.:,_-';
My variant for array in url (/tours/novogodniye-turi/visa=yes;duration=small;transport=4,7,6,2/)
if ( ! function_exists('filter_parse_segment'))
{
function filter_parse_segment($segment, $merge_to_get = FALSE)
{
if(empty($segment))
{
return FALSE;
}
$parameters = explode(";", (string)$segment);
if(empty($parameters))
{
return FALSE;
}
$parameters_array = array();
foreach($parameters as $parameter)
{
if(empty($parameter))
{
continue;
}
$parameter = explode("=", $parameter);
if( ! isset($parameter[0], $parameter[1]) or empty($parameter[0]))
{
continue;
}
if(strpos($parameter[1], ','))
{
$parameter[1] = explode(",", $parameter[1]);
}
$parameters_array[$parameter[0]] = $parameter[1];
}
if($merge_to_get === TRUE)
{
$_GET = array_merge($_GET, $parameters_array);
}
return $parameters_array;
}
}
// --------------------------------------------------------------------
if ( ! function_exists('filter_collect_segment'))
{
function filter_collect_segment($array, $suffix = '', $remove = array())
{
if(empty($array) || ! is_array($array))
{
return '';
}
$segment_str = '';
foreach ($array as $key => $value)
{
if(empty($key) || in_array($key, (array)$remove))
{
continue;
}
if( ! $segment_str == '')
{
$segment_str = $segment_str.';';
}
if( ! is_array($value))
{
$segment_str = $segment_str.$key.'='.$value;
continue;
}
if(empty($value))
{
continue;
}
$parsed_value = '';
foreach ($value as $item)
{
if( ! $parsed_value == '')
{
$parsed_value = $parsed_value.',';
}
if(is_array($item) || empty($item))
{
continue;
}
$parsed_value = $parsed_value.$item;
}
$segment_str = $segment_str.$key.'='.$parsed_value;
}
if($segment_str != '')
{
$segment_str = $segment_str.$suffix;
}
return $segment_str;
}
}
// --------------------------------------------------------------------
if ( ! function_exists('filter_key'))
{
function filter_key($filter_array, $key, $value = NULL)
{
if( ! isset($filter_array[$key]))
{
return;
}
if($value == NULL)
{
return $filter_array[$key];
}
if( ! is_array($filter_array[$key]) && $filter_array[$key] == (string)$value)
{
return $value;
}
if(is_array($filter_array[$key]) && in_array($value, $filter_array[$key]))
{
return $value;
}
return FALSE;
}
}
If you want the solution in the pretty nice URL then you have to loop the array first and then concatenate the elements with some - dash or + plus signs like this;
$array = array(1,2,3,4);
$string = "";
foreach($array as $value){
$string .= $value."-";
}
$string = rtrim($string, "-");
redirect(base_url()."get_products?param=".$string);
And on the next page just get the param and use explode() function with - dash sign to create the array again.
try your url like this
if value you have to pass is
[1,2,3,2]
then
localhost/mysite/index.php/C/X/1,2,3,2
In a simple way you can make the array a string with some special character in between the values of the array.
Then in the landing page you can split the string with the special character and get the array again.
If the values are [1,2,3,4], then make it using a loop "1,2,3,4".
Then pass the string.
In teh landing page split the string with "," and you will again get the array.
Hope it helps you.
Thanks
Why don't you use uri segments for array? You can count uri segments and could use them. Even u could check how many arrays already there.
url.com/1/2/3
http://ellislab.com/codeigniter/user-guide/libraries/uri.html
Note: uri segment doesnt work on main controller index function, you have to define another function than index for example: I don't know what it happens but i think because of htaccess file I'm using do remove index.php.
url.com/uri_segment_controller/go/1/2/3
See:
$class_members = get_class_vars(__CLASS__);
foreach($class_members as $key => $value)
{
if (strpos($key, '_output') === 0)
{
// I want to eval() this
$code = '$this->' . $key . ' = 0;';
}
}
Assume I want to assign the value 0 to all class members that begin with _output. I plan to use eval. Good or bad idea?
You don't need eval() for this. You can use a variable as in $this->{$key}:
foreach($class_members as $key => $value)
{
if (strpos($key, '_output') === 0)
{
// Look mom, no eval()!
$this->{$key} = 0;
}
}
You can just do:
$this->{$key} = 0;
There are only a few situations where eval isn't considered evil.
And this isn't one of them :)
I have a form that passes something like in a URL
?choice=selection+A&choice=selection+C
I'm collecting it in a form with something like (I remember that $_GET is any array)
$temp = $_GET["choice"];
print_r($temp);
I'm only getting the last instance "selection C". What am I missing
I am assuming 'choice' is some kind of multi-select or checkbox group? If so, change its name in your html to 'choice[]'. $_GET['choice'] will then be an array of the selections the user made.
If you don't intend to edit the HTML, this will allow you to do what you're looking to do; it will populate the $_REQUEST superglobal and overwrite its contents.
This assumes PHP Version 5.3, because it uses the Ternary Shortcut Operator. This can be removed.
$rawget = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : false;
$rawpost = file_get_contents('php://input') ?: false;
$target = $rawget;
$_REQUEST = array();
if ($target !== false) {
$pairs = explode('&',$rawget);
foreach($pairs as $pair) {
$p = strpos($pair,'=');
if ($p === false && !empty($pair)) {
$_REQUEST[$pair] = null;
}
elseif ($p === 0 || empty($pair)) {
continue;
}
else {
list($name, $value) = explode('=',$pair,2);
$name = preg_replace('/\[.*\]/','',urldecode($name));
$value = urldecode($value);
if (array_key_exists($name, $_REQUEST)) {
if (is_array($_REQUEST[$name])) {
$_REQUEST[$name][] = $value;
}
else {
$_REQUEST[$name] = array($_REQUEST[$name], $value);
}
}
else {
$_REQUEST[$name] = $value;
}
}
}
}
As it stands, this will only process the QueryString/GET variables; to process post as well, change the 3rd line to something like
$target = ($rawget ?: '') . '&' . ($rawpost ?: '');
All that having been said, I'd still recommend changing the HTML, but if that's not an option for whatever reason, then this should do it.