I have a mysql_query to select * from an 'english' list database and mysql_fetch_assoc returns an array. I try to search word 'flick' (which actually exists in the database) by using in_array() if 'flick' is found, it shouldn't be shown but it is shown. I think in_array function does not find the word 'flick'. Please look at code below:
<?php
error_reporting(E_ALL);
require 'db.php';
function spellcheck($word)
{
$output = array();
$word = mysql_real_escape_string($word);
$words = mysql_query("SELECT `word` FROM `english` WHERE LEFT(`word`, 1) = '" .
substr($word, 0, 1) . "'");
while(($words_row = mysql_fetch_assoc($words)) && (in_array($word, $words_row)==false))
{
similar_text($word, $words_row['word'], $percent);
if($percent > 82)
{
$output[] = $words_row['word'];
}
}
return (empty($output)) ? false : $output;
}
if (isset($_GET['word']) && trim($_GET['word']) != null)
{
$word = $_GET['word'];
$spellcheck = spellcheck($word);
if ($spellcheck !== false)
{
echo '<pre>' . print_r($spellcheck, true) . '</pre>';
} else {
echo '<p>' . $word . ' spelled correctly, or no suggestions founds.</p>';
}
}
?>
<form action="" method="GET">
Check single word spelling:
<input type="text" name="word" />
<input type="submit" value="Check" />
</form>
The code returns:
Array (
[0] => flick
[1] => flicks
)
But it should be:
"spelled correctly, or no suggestions founds."
replace this line
while(($words_row = mysql_fetch_assoc($words)) && (in_array($word, $words_row)==false))
with
while(($words_row = mysql_fetch_assoc($words))) {
if((in_array($word, $words_row)==false)) {
and at bottom close if statement
After 2 days working on my problem I found the answer.
the mistake is in the output of the query by mysql_fetch_assoc. Actually it returns an associative array but every key is added a space (' ') after that.
So, the result is not like abcdefg. The result is like a b c d e f g. It means when I search a special word in the associative array, the in_array() function returns false. Because for example the word 'flick' is not equal to 'flick ' and there is a space after the keys in array. I used trim() function and solved my problem:
while ($rows = mysql_fetch_assoc($query))
{
foreach($rows as $key)
{
$key = trim($key);
$array[] = $key;
}
}
if (in_array($word, $array))
{
echo "The word is spelled correctly";
} else {
foreach($array as $key)
{
similar_text($word, $key, $percent);
if ($percent > 82)
{
$output[] = $key;
}
}
}
tank you for your paying attention to my answer.
Related
I want to make a method that returns keys and values. But only if the keys include the following string "_1" and "__last".
If only one matches then exit the function, only if the two string are included in the key, return the key with the value for a weather.
$infoList = array("_key_1"=>array("time"=>9, "day"=>"Tuesday", "weather"=>"sunny",
"humidity"=>"80%"),
"_key_2"=>array("time"=>5, "day"=>"Tuesday", "weather"=>"cloudy"),
"_key__last"=>array("time"=>3, "day"=>"Sunday", "weather"=>"rainy"))
public function getData() {
$list = array();
foreach($infoList as $key){
if(preg_match('/(_key)_(_1)/', $key) && preg_match('/(_key)_(__last)/', $key) == TRUE){
$list[$key] = $list[$key]["weather"]
}
}
return $list
}
You are making your life so much more difficult that it need be, use str_contains() its easier than building complex REGEX's and getting very confused by the look of it :)
I also fixed a number of other mistakes, such as the foreach that was not going to work, so check all the code.
It is also better to pass data to a function/method otherwise you get into scoping issues!
$infoList = array("_key_1"=>array("time"=>9, "day"=>"Tuesday", "weather"=>"sunny", "humidity"=>"80%"),
"_key_2"=>array("time"=>5, "day"=>"Tuesday", "weather"=>"cloudy"),
"_key__last"=>array("time"=>3, "day"=>"Sunday", "weather"=>"rainy"));
function getData(Array $infoList) {
$list = [];
$found = 0;
foreach($infoList as $key => $val) {
if( str_contains($key, '_1') || str_contains($key, '__last') ) {
$list[$key] = $val["weather"];
$found++;
}
}
if ( $found >= 2 ) {
return $list;
} else {
return false;
}
}
$res = getData($infoList);
if ( $res !== false ){
print_r($res);
} else {
echo 'Not Found';
}
RESULTS
Array
(
[_key_1] => sunny
[_key__last] => rainy
)
If you want to stick with RegEx, you can use positive lookaheads, the same way you check for passwords characters :
<?php
$pattern = '/^(?=.*_1)(?=.*_last).*$/';
$shouldMatch = [
'_1_last',
'foo_1bar_lasthello',
'_last_1',
'foo_lastbar_1hello'
];
echo 'next ones should match : ' . PHP_EOL;
foreach ($shouldMatch as $item)
{
if (preg_match($pattern, $item))
echo $item . PHP_EOL;
}
$shouldNOTMatch = [
'_2_first',
'bar_lasthello',
'foo_las_1hello'
];
echo 'next ones should NOT match : ' . PHP_EOL;
foreach ($shouldNOTMatch as $item)
{
// v------------ check
if (!preg_match($pattern, $item))
echo $item . PHP_EOL;
}
Output :
next ones should match :
_1_last
foo_1bar_lasthello
_last_1
foo_lastbar_1hello
next ones should NOT match :
_2_first
bar_lasthello
foo_las_1hello
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);
I've been trying to get this to work and while I have tried many methods posted on this site on other pages, I can't get any of them to work.
I need to identify the last key so that my results don't have a , at the end. This sounds like such and easy task but I just cant seem to get it to work! At this point I'm guessing I've just had a typo or something that I overlooked. Any help would be greatly appreciated.
This is what I have:
<?php
$searchString = $_GET["s"];
$prefix = 'http://link_to_my_xml_file.xml?q=';
$suffix = '&resultsPerPage=100';
$file = $prefix . $searchString . $suffix;
if(!$xml = simplexml_load_file($file))
exit('False'.$file);
foreach($xml->results->result as $item) {
echo $item->sku . ",";
}
?>
Now this works just fine, it just has a , at the end:
12345,23456,34567,45678,
For reference my xml file is laid out like: results->result->sku, but with a lot more mixed in. I'm just singling out the fields.
Consider identifying the first instead?
$first = true;
foreach($xml->results->result as $item) {
if ($first) {
$first = false;
} else {
echo ',';
}
echo $item->sku;
}
Use rtrim()
foreach($xml->results->result as $item) {
$mystr .= $item->sku . ",";
}
echo rtrim($mystr, ",")
Should output:
12345,23456,34567,45678
Demo!
If your keys are in numerical order like: 0, 1, 2, 3 etc this could be a solution:
foreach($xml->results->result as $key => $item)
{
if( $key > 0 ) echo ", ";
echo $item->sku
}
Possible solution #1:
$first = true;
foreach ($xml->results->result as $item) {
if ($first) {
$first = false;
} else {
echo ', ';
}
echo $item->sku;
}
Possible solution #2:
$items = array();
foreach ($xml->results->result as $item) {
$items[] = $item->sku;
}
echo join(', ', $items);
You can just put everything in a string and then run:
substr($yourstr, 0, -1);
on your code to remove the last character:
http://de1.php.net/manual/en/function.substr.php
Or get the total number of entries in your array and count your position
I have a question about arrays and foreach.
If i have an array like this:
$test_arr = array();
$test_arr['name1'] = "an example sentence";
$test_arr['anything'] = "dsfasfasgsdfg";
$test_arr['code'] = "4334refwewe";
$test_arr['empty1'] = "";
$test_arr['3242'] = "";
how can I do a foreach and "pick" only the ones that have values? (in my array example, would only take the first 3 ones, name1, anything and code).
I tried with
foreach ($test_arr as $test) {
if (strlen($test >= 1)) {
echo $test . "<br>";
}
}
but it doesn't work. Without the "if" condition it works, but empty array values are taken into consideration and I don't want that (because I need to do a <br> after each value and I don't want a <br> if there is no value)
Sorry if I don't explain myself very well, I hope you understand my point. Shouldn't be too difficult I guess..
Thanks for your help !
Maybe will work
foreach ($test_arr as $test) {
if (strlen($test)!=="") {
echo $test . "<br>";
}
}
Your solution with corrected syntax:
foreach ($test_arr as $test) {
if (strlen($test)>=1) {
echo $test . "<br>";
}
}
Since empty strings are false, you could just do this (but you'd exclude 0's with the if):
foreach ($test_arr as $key => $val) {
if ($val) {
echo $val. "<br>";
}
}
If it has to be an empty string then (excluding 0 and FALSE):
foreach ($test_arr as $key => $val) {
// the extra = means that this will only return true for strings.
if ($val !== '' ) {
echo $val. "<br>";
}
}
Since it looks like you're using an associative array, you should be able to do this:
foreach( $test_arr as $key => $value )
{
if( $value != "" )
{
echo $value . "<br />";
}
}
As shown, you can test $value for an empty string directly. Since this is precisely the test you are trying to accomplish, I would hope that this would solve your problem perfectly.
On another note, this is pretty straight forward and should be very maintainable in the future when you've forgotten exactly what it was that you were doing!
You are better off to use a while loop like this:
while(list($test_key, $test_value) = each($test_arr))
{
if($test_value != "") { echo $test_value . "<br/>"; }
}
reset($test_arr);
If your array gets large, the while will be much faster. Even on small arrays, I have noticed a big difference in the execution time.
And if you really don't want the array key. You can just do this:
while(list(, $test_value) = each($test_arr))
{
if($test_value != "") { echo $test_value . "<br/>"; }
}
reset($test_arr);
You can check if the value is emtpy with empty().
Note that values like 0 or false are considered empty as well, so you might have to check for string length instead.
just a simple typing error:
foreach ($test_arr as $test) {
if (strlen($test) >= 1) {
echo $test . "<br>";
}
}
Try this:
foreach ($test_arr as $test) {
if (strlen($test) > 0) {
echo $test . "<br>";
}
}
I'm trying to compare two strings. When I echo them, they appear to be identical, yet when I compare them with the '==' operator, it returns false. For example, when running the code below on my database. It outputs things like "APPARENTLY Apple does not equal Apple". What is the reason?
if ($this->data['list_text']) { // The user has entered into textarea
$list = nl2br($this->data['list_text']);
$list_array = explode('<br />', $list);
$ranking = 1;
$company_array = $this->CompanyList->CompanyRanking->Company->find('list', null);
// This is the comparison bit
foreach ($list_array as $key => $value) {
$companyId = null;
foreach ($company_array as $key2 => $value2) {
if ($value2 != $value) {
echo 'APPARENTLY ' . $value2 . ' does not equal ' . $value;
} else {
$companyId = $key2;
break;
}
}
$this->data['CompanyRanking'][$ranking]['ranking'] = $ranking;
$this->data['CompanyRanking'][$ranking]['company_id'] = $companyId;
$ranking++;
}
}
Try var_dump() instead of echo.
echo 'APPARENTLY '.$value2.' does not equal '.$value;
echo '<pre>Debug: ';
echo 'value='; var_dump($value);
echo 'value2='; var_dump($value2);
echo '</pre>';
It provides additional information. E.g. the actual type. And the length of strings.
Do the strings have any extra whitespace you're not seeing? Try trimming them.
Try to check the encoding of both strings compared.
Maybe it is UTF-8 compared with ISO 8859-1 with some weird characters.
I agree with Olafur. I removed trim and replaced it with a preg_replace due to the fact you are assuming $value and $value2 are companyIDs. You can make a quick modification on these if the companyID is supposed to be alphanumeric, contain hyphens, etc... This version should do it:
if ($this->data['list_text']) {
$list = nl2br($this->data['list_text']);
$list_array = explode('<br />', $list);
$ranking = 1;
$company_array = $this->CompanyList->CompanyRanking->Company->find('list',null);
foreach ($list_array as $key => $value) {
// remove any non digit characters
$value = preg_replace('/[^0-9]/i','', $value);
$companyId = null;
foreach ($company_array as $key2 => $value2) {
// remove any non digit characters
$value2 = preg_replace('/[^0-9]/i','', $value2);
if ($value2 != $value) {
echo 'values not equal';
} else {
$companyId = $key2;
break;
}
}
$this->data['CompanyRanking'][$ranking]['ranking'] = $ranking;
$this->data['CompanyRanking'][$ranking]['company_id'] = $companyId;
$ranking++;
}
}
Try trim() for any white space as well as var_dump() to see if anything else is being passed with it.