Comparing dynamic arrays together with an if then else statement - php

In my code I want to replace the following:
if($file['domain']=="VALUE" || $file['domain']=="VALUE" || $file['domain']=="VALUE" || $file['domain']=="VALUE"){}
else{}
with something like this that can be changed in a more generic config file:
$domains_to_exclude="VALUE,VALUE,VALUE,VALUE";
The values of both arrays change and vary. What I want to do is if the $file['domain'] matches the value of domains_to_exclude is to skip over it.
I am going in the right direction by trying something like this. So far I've not had any success.
$myArray = explode(',', $domains_to_exclude);
$count = count($file);
for ($i=1; $i<$count; $i++)
{
if ($myArray[$i] !== $file['domain'])
{
$domain=$file['domain'];
$domainn = str_replace("", "", $domain);
echo'<option value="'.$domain.'">'.$domainn.'</option>';
}
else {}
}

$myArray = explode(',', $domains_to_exclude);
if (!in_array($file['domain'], $myArray)) {
// Domain is ok, process file
}
in_array($str, $arr) checks if any of the values in $arr equals $str.
And also, you don't have to have that else block there if it is empty. But it won't affect your code negatively either.

you can do something like this:
$domains_to_exclude = array(...); //make an array of your "VALUES"
$file = array('foo', 'bar'); // your $file array
if(count(array_intersect($domains_to_exclude, $file)) > 0){
// at least a match was found
}

Related

PHP file with multiple lines to array and key with value

I have files with lines in it where i want to create array with a key and value
file1 has for example:
thisisline = aline
thisisalsoaline = oke
whereiamaline = check
file2 has
thisisline = aline
thisisalsoaline = oke
whereiamaline = checker
what i am trying to create but no luck to have a result which is :(
thisisline => aline
thisisalsoaline => oke
whereiamaline => check
i tried with explode but then it was like
[0] => thisisline = aline
the endgoal is to have 2 files to compare with array_diff_key so that i can identify the line whereiamaline = checker
Could somebody point me to the correct direction?
Thank you
Your files look like ini-files. php already has parse_ini_file function, which will return key => value array.
Next, correct function is array_diff_assoc:
$a = parse_ini_file('file1');
$b = parse_ini_string('file2');
print_r(array_diff_assoc($a, $b));
Because array_diff_key returns keys which are in first array, but not in second, which is not your case.
You can do it with explode function with delimeter =, like:
$finall_array = array();
$handle = fopen("file.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$le = explode("=",$line);
$finall_array[$le[0]] = $le[1];
}
fclose($handle);
} else {
// here goes error file opeping
}
Then just use $final_array like your output
You can do it this way.
foreach(file("file1.txt") as $line) {
$pieces = explode("=", $line);
//Do whatever you want to do with $pieces here. $pieces[0] and $pieces[1]
//Trim the values of $pieces too.
}
Another way is:
for each(file("file1.txt") as $line) {
$res[] = array_map('trim', explode('=', $line));
}
This one will directly populate the $res[] array with arrays of each line (which are trimmed)
So i used the parse_in_file together with the arra_diff_assoc and then it is
<?php
$file1 = parse_ini_file("master_manager.txt");
$file2 = parse_ini_file("master_manager1.txt");
echo "<pre>";
$myarray = array_diff_assoc($file1, $file2);
foreach ($myarray as $key => $value){
echo $key." = ".$value."\n"; }
echo "</pre>";
but then if a line contains false or true it gives a 1 or nothing (null) how to prevent that? –

How to continuously push user input data into $_SESSION array and then retrieve it?

I am trying to get my head around the way PHP sessions work. I am simply trying a hangman game where the first player inputs a secret word, a second player then starts to guess one letter at a time.
Let's says that the secret word is cat, player two tries, c then a then s. I would like the final output to be c a _.
<?php
session_start();
global $word;
global $guess;
global $hangman;
if (isset($_POST['player1'], $_POST['word'])) {
$_SESSION['word'] = $_POST['word'];
$word = $_SESSION['word'];
}
if (isset($_POST['player2'], $_POST['guess'])) {
$_SESSION['guess'] = $_POST['guess'];
$guess = $_SESSION['guess'];
}
$counter = 0;
$word = strtolower($_SESSION['word']);
$guess = strtolower($_SESSION['guess']);
echo $word . "<br>";
$found = [];
$counter = 0;
for ($i = 0; $i < strlen($word); $i++) {
if ($counter < strlen($word)) {
if (strpos($word[$i], $guess) !== false) {
$found[] = $guess;
$counter++;
} else {
$found[] = " _ ";
}
}
}
print_r($found);
Instead of printing out all the contents the found array, I am only getting one single letter to print every time. However, I would like to see the full concatenated string as I've mentioned above.
Here is what the output looks like:
How to continuously push user input data into $_SESSION array and then retrieve it?
An easy way to do that is by binding a variable with an element in the $_SESSION array.
This is a useful trick that you won't find in the manual.
A simple example:
$foo =& $_SESSION['foo'];
That assignment will bind $foo and $_SESSION['foo'] to the same value,
so every update to $foo is also an update to $_SESSION['foo'].
Here is an example usage in the style of your hangman game:
<?php
session_start();
$word =& $_SESSION['word']; //bind $word with $_SESSION['word']
$found =& $_SESSION['found']; //bind $found with $_SESSION['found']
if (isset($_REQUEST['word'])) {
$word = str_split($_REQUEST['word']);
$found = array_fill(0, count($word), '_');
}
if (isset($_REQUEST['guess'], $word, $found)) {
$guess = array_fill(0, count($word), $_REQUEST['guess']);
$found = array_replace($found, array_intersect($word, $guess));
}
echo join(' ', $found);
With the binding, the values of $word and $found will be saved as a part of the session data,
without the need to do $_SESSION['word'] = $word; and $_SESSION['found'] = $found; anywhere in the script.
Note that I use $_REQUEST instead of $_POST to make it easier to test with a browser.
Modify as desired.
Make the $found as a string variable.Instead of pushing in $found[] ,concatenate $guess Like $found .= $guess;
You should save what was already found between requests, since now you are just searching the $_SESSION['word'] for the char in the last request.
if ( isset($_POST['player1']) && !empty($_POST['word']) ) {
$_SESSION['word'] = str_split( $_POST['word'] );
// ceate empty array for storing the already found chars
$_SESSION['found'] = str_split( str_repeat( " ", strlen($_POST['word']) ) );
}
if ( isset($_POST['player2']) && !empty($_POST['guess']) ) {
array_walk( $_SESSION['word'], function( $v, $k ) {
if ( $v == $_POST['guess'] )
$_SESSION['found'][$k] = $v;
});
}
if ( $_SESSION['word'] == $_SESSION['found'] )
echo 'Game Over';
print_r( $_SESSION['found'] );
You are overwriting your $_SESSION['guess'] with:
$_SESSION['guess'] = $_POST['guess'];
on every submission.
I would recommend that you store your posted guesses as a subarray of letters like:
$_SESSION['guesses'][] = $_POST['guess'];
Then you will never overwrite earlier guesses.
This will mean you will have a session array with this type of structure:
$_SESSION=[
'player1' => 'me',
'word' => 'cat',
'player2' => 'myself',
'guesses' => ['a','c']
];
From here, you can call str_split() on $_SESSION['word'] and check for found/remaining letters using $_SESSION['guesses'] and array comparison functions.
Here are some untested portions of code that may help you along...
session_start();
if (!isset($_SESSION['player1'], $_SESSION['word'])) { // no stored player1 or word
if (!isset($_POST['player1'], $_POST['word'])) { // no posted player1 or word
// show form with player1 and word fields
} else {
$_SESSION=['player1'=>$_POST['player1'],'word'=>strtolower($_POST['word'])]; // store player1 and word
}
} elseif (!isset($_SESSION['player2'], $_SESSION['guesses'])){ // no stored player2 or guesses
if (!isset($_POST['player2'], $_POST['guess'])) { // no posted player2 or guess
// show form with player2 and first guess
} else {
$_SESSION['player2'] = $_POST['player1']; // store player2
$_SESSION['guesses'] = [strtolower($_POST['guess'])]; // store guessed character as first element of subarray
}
} elseif (isset($_POST['guess'])) {
$_SESSION['guesses'][] = strtolower($_POST['guess']); // store guessed character
}
And further down script here are some pieces...
$secret_letters=array_unique(str_split($_SESSION['word'])); // unique secret word letters
$found_letters=array_intersect($secret_letters,$_SESSION['guesses']); // unique found letters
if($secret_letters===$found_letters){
// player2 guessed all of the secret letters, set off fireworks
}else{
// some useful bits of code...
$not_yet_found=array_diff($secret_letters,$_SESSION['guesses']);
$underscored=str_replace($not_yet_found,'_',$_SESSION['word']); // e.g. 'ca_'
$space_out=implode(' ',str_split($underscored)); // e.g. 'c a _'
$wrong_letters=array_diff($_SESSION['guesses'],$secret_letters); // letters guessed but not part of secret word
// when count($wrong_letters) reaches your designated limit, then the guesser loses
$avaliable_letters=array_diff(range('a','z'),$_SESSION['guesses']);
$select="<select name=\"guess\"><option>".implode('</option><option>',$available_letters)."</option></select>";
}
I should also note, there are many ways to tackle this project. You should have a look at count_chars(), it has multiple modes which you should research and consider.
There will be regex methods that may be helpful, but I won't open up that can for you.
I see your problem now. you didn't save or hold the previous guess because your found[] array variable is always empty.
try to save the found result in a session
and change this following line of code:
for ($i = 0; $i < strlen($word); $i++) {
if ($counter < strlen($word)) {
if (strpos($word[$i], $guess) !== false) {
$found[] = $guess;
$counter++;
} else {
$found[] = " _ ";
}
}
}
TO:
$counterWord = strlen($word);
for ($i = 0; $i < $counterWord ; $i++) {
if (strpos($word[$i], $guess) !== false) {
$found[$i] = $guess; // $i indicates what index should be changed
} else {
if(!isset($found[$i])){
$found[$i] = "_";
}
}
$_SESSION['found'] = $found;
and add this line of code under the declaring of your $found array variable:
$found = [];
if(isset($_SESSION['found'])){ //checker if the variable is set and not empty
$found = $_SESSION['found']; // getting the value of found and store it in found variable
}

Compare elements of two arrays php

So I have two arrays:
$badwords = array('bad-word', 'some-racist-term', 'nasty', 'bad-language');
$inputphrases = array('this-is-sentence-with-bad-word', 'nothing-bad-here', 'more-clean-stuff', 'this-is-nasty', 'this-contains-some-racist-term', 'one-more-clean', 'clean-clean', 'contains-bad-language');
I need to compare elements of input phrases array with bad words array and output new array with phrases WITHOUT bad words like this:
$outputarray = array('nothing-bad-here', 'more-clean-stuff','one-more-clean', 'clean-clean');
I tried doing this with two foreach loops but it gives me opposite result, aka it outputs phrases WITH bad words.
Here is code I tried that outputs opposite result:
function letsCompare($inputphrases, $badwords)
{
foreach ($inputphrases as $inputphrase) {
foreach ($badwords as $badword) {
if (strpos(strtolower(str_replace('-', '', $inputphrase)), strtolower(str_replace('-', '', $badword))) !== false) {
$result[] = ($inputphrase);
}
}
}
return $result;
}
$result = letsCompare($inputphrases, $badwords);
print_r($result);
this is not a clean solution, but hope, you'll got what is going on. do not hesitate to ask for clearence. repl.it link
$inputphrases = array('this-is-sentence-with-bad-word', 'nothing-bad-here', 'more-clean-stuff', 'this-is-nasty', 'this-contains-some-racist-term', 'one-more-clean', 'clean-clean', 'contains-bad-language');
$new_arr = array_filter($inputphrases, function($phrase) {
$badwords = array('bad-word', 'some-racist-term', 'nasty', 'bad-language');
$c = count($badwords);
for($i=0; $i<$c; $i++) {
if(strpos($phrase, $badwords[$i]) !== false){
return false;
}
}
return true;
});
print_r($new_arr);

in_array() keeps appending values if looping through db rows

I need to identify every instance where a value in one array (needle) occurs in another array (haystack). in_array() seems to be my best option, and the code below works perfectly until I need to use it on rows fetched from a db - it keeps appending values instead of setting them each time it's called.
While I can't actually use unset() in this situation, I was surprised to discover that even that didn't seem to resolve the problem.
UPDATE - Example of what's being returned
I temporarily changed the db values so that $needles has only value per row (in order to make it possible to sort through the values filling up my screen ;-))
False;
False; False; True;
False; False; True; False; True;
False; False; True; False; True; False; True;
False; False; True; False; True; False; True; False;
This works correctly
(I've posted a functional example here)
$needles = array('John', 'Alex');
$haystack = array('John','Alexander','Kim', 'Michael');
foreach ($needles as $needle) {
if (in_array($needle, $haystack) ) {
$Match = 'True';
}
else {
$Match = 'False';
}
}
This keeps appending values - Edited to reflect the code I'm using
$Customer_Categories_Arr = array('Casual','Trendy');
if ($stmt->columnCount()) {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$Product_Categories_Arr[]=$row["Taste_Category"];
// Use when column contains CSV
// $Product_Categories_Arrx = explode(',', trim($Product_Categories_Arr[0]));
foreach ($Product_Categories_Arr as $Product_Category_Arr) {
if (in_array($Product_Category_Arr, $Customer_Categories_Arr)){
$Matches_Product_Category = "True";
} else {
$Matches_Product_Category = "False";
}
echo $Product_Category_Arr, ', ', $Matches_Product_Category, '; ';
}
}
}
It is not really clear what you are trying to do. But maybe this would help:
$customerCategories = array('Casual', 'Trendy');
if( $stmt->columnCount() ){
while( $row = $stmt->fetch( PDO::FETCH_ASSOC )){
$productCategoryRow = $row[ 'Taste_Category' ];
// If it is not working, try uncommenting the next line
// $productCategories = [];
$productCategories = explode( ',', trim( $productCategoryRow ));
$match = "False";
foreach( $productCategories as $productCategory ){
if( in_array( $productCategory, $customerCategories )){
$match = "True";
}
echo $match . ";";
}
}
}
This prints your result on the screen every time a loop is done. Is this what you mean?
If you want the second block of code to do what the first block of code (which works correctly) does, then the second block should look like this -
if ($stmt->columnCount()) {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$needle =$row["product_var"];
$Match = "False";
if (in_array($needle, $haystack)){
$Match = "True";
}
}
}
You don't need do use the foreach because that is replaced by the while loop in the second block.
I am going to try an solve this. I think the problem is with:
$needles[]=$row["product_var"];
I think this should be:
$needles=$row["product_var"];
The column "product_var" contains an CSV (as you mentioned), so I can make an example like this:
$csv = "jake;john;alex;kim";
An example with brackets ($needles[]):
for($i=0; $i<5; $i++) {
$needles[] = explode(";", $csv);
echo(count($needles).", ");
}
returns:
1, 2, 3, 4, 5,
edit (for more explaining):
if I use print_r I see the array expanding, exactly how it happens in your example:
step 1: it adds an array to $needles with values ('jake','john','alex','kim')
step 2: it adds an array to $needles, so it contains 2x the values ('jake','john','alex','kim')
step 3: it adds an array to $needles, so it contains 3x the values ('jake','john','alex','kim')
etc.
Now without the brackets ($needles):
for($i=0; $i<5; $i++) {
$needles = explode(";", $csv);
echo(count($needles).", ");
}
This returns:
4, 4, 4, 4, 4,
And every time the array simply contains the values ('jake','john','alex','kim') -which is what you want.
Could this explain the "expanding values"? (or am I just doing something really stupid which has nothing to do with your problem??)
edit:
If this is what is going wrong, then you are adding to an array, instead of only using the new array from $row["product_var"] (hope this makes any sense; it seems I am pretty bad at explaining what's happening).

wildcard array comparison - improving efficiency

I have two arrays that I'm comparing and I'd like to know if there is a more efficient way to do it.
The first array is user submitted values, the second array is allowed values some of which may contain a wildcard in the place of numbers e.g.
// user submitted values
$values = array('fruit' => array(
'apple8756apple333',
'banana234banana',
'apple4apple333',
'kiwi435kiwi'
));
//allowed values
$match = array('allowed' => array(
'apple*apple333',
'banana234banana',
'kiwi*kiwi'
));
I need to know whether or not all of the values in the first array, match a value in the second array.
This is what I'm using:
// the number of values to validate
$valueCount = count($values['fruit']);
// the number of allowed to compare against
$matchCount = count($match['allowed']);
// the number of values passed validation
$passed = 0;
// update allowed wildcards to regular expression for preg_match
foreach($match['allowed'] as &$allowed)
{
$allowed = str_replace(array('*'), array('([0-9]+)'), $allowed);
}
// for each value match against allowed values
foreach($values['fruit'] as $fruit)
{
$i = 0;
$status = false;
while($i < $matchCount && $status == false)
{
$result = preg_match('/' . $match['allowed'][$i] . '/', $fruit);
if ($result)
{
$status = true;
$passed++;
}
$i++;
}
}
// check all passed validation
if($passed === $valueCount)
{
echo 'hurray!';
}
else
{
echo 'fail';
}
I feel like I might be missing out on a PHP function that would do a better job than a while loop within a foreach loop. Or am I wrong?
Update: Sorry I forgot to mention, numbers may occur more than 1 place within the values, but there will only ever be 1 wildcard. I've updated the arrays to represent this.
If you don't want to have a loop inside another, it would be better if you grouped your $match regex.
You could get the whole functionality with a lot less code, which might arguably be more efficient than your current solution:
// user submitted values
$values = array(
'fruit' => array(
'apple8756apple',
'banana234banana',
'apple4apple',
'kiwi51kiwi'
)
);
$match = array(
'allowed' => array(
'apple*apple',
'banana234banana',
'kiwi*kiwi'
)
);
$allowed = '('.implode(')|(',$match['allowed']).')';
$allowed = str_replace(array('*'), array('[0-9]+'), $allowed);
foreach($values['fruit'] as $fruit){
if(preg_match('#'.$allowed.'#',$fruit))
$matched[] = $fruit;
}
print_r($matched);
See here: http://codepad.viper-7.com/8fpThQ
Try replacing /\d+/ in the first array with '*', then do array_diff() between the 2 arrays
Edit: after clarification, here's a more refined approach:
<?php
$allowed = str_replace("*", "\d+", $match['allowed']);
$passed = 0;
foreach ($values['fruit'] as $fruit) {
$count = 0;
preg_replace($allowed, "", $fruit, -1, $count); //preg_replace accepts an array as 1st argument and stores the replaces done on $count;
if ($count) $passed++;
}
if ($passed == sizeof($values['fruit']) {
echo 'hurray!';
} else {
echo 'fail';
}
?>
The solution above does not remove the need for a nested loop, but it merely lets PHP do the inner loop, which may be faster (you should actually benchmark it)

Categories