I have a input field and a array of email from DB table.
I am comparing the similarity of the input field to the array.
But some how, I am stuck with the loop.
Does that loop check compare each email with the input field?
It always bring me to google.com no matter what i input same or not
Here's the code from the controller:
if (isset($_POST['btn_free_download']))
{
// Get current input email from input field
$email = $this->getRequest()->getParam('email');
// Get all emails from the user
$referred_users = $this->_helper->user()->getReferredUsers()->toArray();
// Check the similarity which it with a loop
foreach ($referred_users as $referred_user)
{
similar_text($email, $referred_user['email'], $similar);
}
// If yes, Pop up message or redirect to some page
if ($similar < 97)
{
$this->_redirect('http://google.com');
}
// If not, redirect user to free download page
else
{
$this->_redirect('http://yahoo.com');
}
}
I think you need to check the manual . Foreach function is same wether you use it on zend or any other framework or raw php only.
$referred_users = $this->_helper->user()->getReferredUsers()->toArray();
$referred_users will probably hold an array of emails from the table
user, say:
$referred_users = array("one#email.com", "two#email.com", "three#email.com")
then when you use foreach loop it will iterate through each of the
emails in the array
foreach ($referred_users as $referred_user)
{
// for the first loop $referred_user = one#email.com, for second time $referred_user = two#email.com and goes on
similar_text($email, $referred_user['email'], $similar);
}
Now let us discuss your logic here:
// If yes, Pop up message or redirect to some page
if ($similar < 97)
{
$this->_redirect('http://google.com');
}
// If not, redirect user to free download page
else
{
$this->_redirect('http://yahoo.com');
}
Until and unless the last element in the array $referred_users is exactly equal to your $email
i.e. $email = "three#email.com"
you will always be given result for $similar less than 97% which means you will be redirected to google.
Which I assume you are not trying to do and probably not familiar with foreach function which is why you are not getting the expected result.
Assuming you are trying to do something like, check for the emails in the array if any of the email in the array matches (if array is from table check if the email entered from param is equal to any of the emails in the table) then redirect to somewhere or show some message else carry on. Solution below might be helpful to you.
$similarText = false;
foreach ($referred_users as $referred_user)
{
// for the first loop $referred_user = one#email.com, for second time $referred_user = two#email.com and goes on
similar_text($email, $referred_user['email'], $similar);
if ($similar > 97) {
$similarText = true;
break;
}
}
// If yes, Pop up message or redirect to some page
if ($similarText)
{
$this->_redirect('http://google.com');
}
// If not, redirect user to free download page
else
{
$this->_redirect('http://yahoo.com');
}
Hope you got the idea. But please do check the manual before posting a question in the future.
Related
I want to loop through a few emails so that every time a form is submitted to myform.php, a different user is emailed.
Please note I am not looking for any functions to send mail. It happens to be emails being used, but the point is I need to know how to loop through a variable from a list of options.
This question isn't actually about emailing, because the form already works and sends email using a variable named $mail_to. Instead, this question is about looping a PHP variable each time a form is submitted.
Whatever I can do to loop them, the rest of the form works when putting an email into $mail_to like
$mail_to = 'user1#mycompany.com';
What I want to do is instead of putting one email into $mail_to, instead I want to loop through a few emails. For example,
Emails:
user1#mycompany.com
user2#mycompany.com
user3#mycompany.com
user4#mycompany.com
In PHP form:
$email_looped = [???];
$mail_to = $email_looped;
Above, [???] is simply me saying in human terms I don't know what to do here.
Effectively, it will work like this in real time:
1st Visitor submits form from website >> $mail_to = 'user1#mycompany.com';
2nd Visitor submits form from website >> $mail_to = 'user2#mycompany.com';
3rd Visitor submits form from website >> $mail_to = 'user3#mycompany.com';
4th Visitor submits form from website >> $mail_to = 'user4#mycompany.com';
5th Visitor submits form from website >> $mail_to = 'user1#mycompany.com';
etc
How can I make it so that every time the form is posted to myform.php (from mypage.html), it chooses the next email in the list and loops them?
You could store the last index in a text file or database, retrieve that value on the next request, and use it to get the next item in the array. Tons of ways to accomplish this, some pseudo code to get you started.
function storeCurrentEmail(int $currentIndex): void
{
// return \Database::table->store('lastEmailIndex', $currentIndex);
// return file_put_contents("/path/to/cached/file.txt", $currentIndex);
}
function getNextEmail(): array
{
// $lastEmailIndex = file_get_contents("/path/to/cached/file.txt");
// $lastEmailIndex = \Database::table->get('lastEmailIndex');
$lastEmailIndex = 3; // for illustrative purposes
$emails = [
'user1#mycompany.com',
'user2#mycompany.com',
'user3#mycompany.com',
'user4#mycompany.com'
];
if ($lastEmailIndex >= sizeof($emails)) {
$lastEmailIndex = 0;
}
return [
$emails[$lastEmailIndex],
$lastEmailIndex
];
}
list($mail_to, $lastIndex) = getNextEmail();
storeCurrentEmail($lastIndex);
\Mail::sendTo($mail_to);
Here I have solved it rather simply:
first create a file in current directory named current.txt and write a 0 in it.
php code:
$emails = [
'user1#mycompany.com',
'user2#mycompany.com',
'user3#mycompany.com',
'user4#mycompany.com'
];
$lastEmailIndex = file_get_contents("current.txt");
$max = count($emails) - 1;
if ($lastEmailIndex >= $max) {
$lastEmailIndex = 0;
file_put_contents("current.txt",0);
} else {
file_put_contents("current.txt",#file_get_contents("current.txt")+1);
$lastEmailIndex = file_get_contents("current.txt");
}
usage:
echo '<script>alert("'. $emails[$lastEmailIndex] . '")</script>';
Now it will loop through all available items, and you can add as many items to the array as you want.
PHP can be brutally simple, enjoy ;)
targets.txt:
user1#example.com
user2#example.com
user3#example.com
user4#example.com
example.php
//read and trim the targets file
$targets = file_get_contents('targets.txt');
$targets = trim($targets," \r\n");
$arr = explode("\n",$targets);
$mail_to = $arr[0];
//now rotate the file
$temp = array_shift($arr);
$arr = array_merge($arr,array($temp));
file_put_contents('targets.txt', implode("\n",$arr));
echo $mail_to;
So I'm making a webshop, well, trying to atleast for a course project using WAMP. But when trying to register new users and in the process checking their password against a list of common ones the use of fgets() returns an empty string.
if(empty(trim($_POST["password"]))){
...
} elseif (!checkPassword($_POST["password"])) {
$password_err = "Password to common.";
echo "<script>alert('Password to common.'); location.href='index.php';</script>";
}
The checkPassword() is where the fault lies.
function checkPassword($passwordtocheck) {
$passwordtocheck = strtolower($passwordtocheck);
$common_passwords = fopen("commonpasswords.txt", "r");
while(!feof($common_passwords)) {
$check_against = fgets($common_passwords);
echo "<script>alert('Checking $passwordtocheck against $check_against.'); location.href='index.php';</script>";
if($check_against == $passwordtocheck) {
fclose($common_passwords);
return false;
}
}
fclose($common_passwords);
return true;
}
Lets say that I input the password 12345678 when registering, then the scripted alert will say "Checking 12345678 against ." and send me back to index.php. So it looks like it doesn't succeed in reading the file at all. The commonpasswords.txt is in the same folder as the rest of the files and with a single password on each row.
And there is no problem opening the file to begin with either, if I do this instead:
$common_passwords = fopen("commonpasswords.txt", "a");
fwrite($common_passwords, "test");
'test' will appear at the bottom of the file under the existing words on its own row without a hitch. And this is where I'm at, would appreciate whatever input people can give!
EDIT; I do understand that this probably breaks a ton of good-practice 'rules' in general and regarding security. But the website is not really supposed to function or look good, it just need to barely work so that we can later try and use different methods of attacking it and the connected database.
If you insist on doing this yourself – which I do not recommend – you can simplify things a lot by using the file() function. This returns an array of every line in the file. Then use array_filter(); it runs a callback on each element of the array where you can check if there's a match with your password. If the callback returns false, the element is removed from the array. After that, if you have any elements left you know there was a match.
function checkPassword($pwd) {
$pwd = strtolower($pwd);
$common = file("commonpasswords.txt", FILE_IGNORE_NEW_LINES);
$results = array_filter($common, function($i) use ($pwd) {return $i == $pwd;});
return count($results) === 0;
}
But really, there are dozens of libraries out there to check password strength. Use one of them.
Or, as pointed out in the comment, even simpler array_search:
function checkPassword($pwd) {
$pwd = strtolower($pwd);
$common = file("commonpasswords.txt", FILE_IGNORE_NEW_LINES);
return array_search($pwd, $common) === false;
}
In a foreach loop, say I wanted to do the following
foreach($items as $item)
{
// charge a user for purchasing an item - IS BEING DONE THROUGH AN API CALL WITH STRIPE
// ie: \Stripe\Charge::create(...);
// save some info to a database
// using Laravel for this project so this is within a DB::transaction(...);
// send a notification email to the buyer
// Emails are being queued to avoid slowing down the request
// ie: Mail::queue(...);
}
I would like an all or nothing situation to occur. For example, if an error occurs during the iteration, then NONE of the items are charged, no information is saved to the database, and the buyer does not get a notification email. However, if the foreach loop successfully iterates over each item, then charge the user, save info to database, and send notification email. How do I do this?
I would recommend using Transactions and notifying the buyer at the end.
Mysqli Example:
$dbConn->begin_transaction();
try{
foreach($ítems as $item){
//Whatever you are going to do
}
if($dbConn->commit()){
//Notify buyer about all the transactions, the user doesn't receives the notification unless the commit was succesful
}
catch(Exception ex){
$dbConn->rollback();
}
Additionally you could verify the return values of the mysqli functions, I Just wanted to focus on the transaction use.
You have options.
Easiest way i can think of is loop over the array twice; the first time checking the condition and the 2nd only if the first run through found no problems.
$isGoodToGo = true;
foreach($items as $item) {
if (conditon met) {
$isGoodToGo = false;
break; // stop iterating over the array cause condition is met
}
}
if ($isGoodToGo) {
foreach($items as $item) {
// charge a user for purchasing an item
// save some info to a database
// send a notification email to the buyer
}
}
You might need to add some more detail as per #Terminus as well as if/why you are charging each item separately. But depending on your needs, you could build the db query during the loop without executing it until the end of the loop. You would then have to roll back any charges (as per your implementation) and then send one or more emails as appropriate.
You can count the no of items in the array and make some changes to make it work:
$result = count($items);
$c = 0;
foreach($items as $item)
{
// charge a user for purchasing an item -- instead add it to a buffer as total
//amount.
// save some info to a database ---instead prepare your db statements here
// send a notification email to the buyer.--this could be sent out for all the
//items in the order together outside the loop instead of inside the loop.
$c = $c + 1;
}
if($c == $cc)
{
//execute your prepared statements here..and also the other email and charging stuff.
}
else{
//Error code.
}
Using PHP and making a SELECT query from DB I am getting an output I don't like.
I start like this:
$details = Db::getInstance()->executeS($sql);
And I get, after a
echo json_encode($details);
For debug purposes:
[{"email":"test#on.gr","lastname":"TEST","firstname":"TEST1","id_lang":"1","id_order":"1"}]
[{"email":"test#on.gr","lastname":"OTHER","firstname":"DIFFERENT","id_lang":"1","id_order":"2"}]
[{"email":"test#on.gr","lastname":"THIRD","firstname":"DIFFERENT","id_lang":"1","id_order":"3"}]
[{"email":"new#on.gr","lastname":"THIRD","firstname":"NEW","id_lang":"1","id_order":"4"}]
What I want is to transform array $details to check on each "line" if the email column has unique values on the whole output. If yes to delete the lines that contain the duplicate entries and leave only the first that contain it.
Desired output:
[{"email":"test#on.gr","lastname":"TEST","firstname":"TEST1","id_lang":"1","id_order":"1"}]
[{"email":"new#on.gr","lastname":"THIRD","firstname":"NEW","id_lang":"1","id_order":"4"}]
(As you see lines with id order 2 and 3 where removed as they have the same email with the first)
Any kind of help will be highly appreciated.
Edit: just wanted to add up here that my code isn't in PHP. You have to change it.
Do an ORDER BY email command in the select statement.
Pseudo Code:
Loop through results:
String email1 = "";
String email2 = "";
for (i=0;i<(Detailssize); i++){
email2 = details[email][i]; //Do whatever you need to do to access the value of the email key here.
if(email2 != email1){
KEEP IT
}
else{
THROW AWAY
}
email1 = email2;
}
Obviously this is not PHP. It has been a while since i coded php. Nonetheless logically this should still work. I'm sure theres a way to change your SELECT statement to only return one from each value but i'm not good enough at SQL for that. This isn't as good of a solution but hope it helps.
Keep a list of emails you've seen before; whenever you encounter an email that has been seen before, skip that row.
Like this:
$newSet = array();
$seenBefore = array();
foreach( $details as $row ) {
if( isset( $seenBefore[ $row['email'] ) ) {
continue; // jump to the next row
}
// this email address must be new; add it to things we've seen before then add this row to the newSet
$seenBefore[$row['email']] = true;
$newSet[] = $row;
}
Then output $newSet in whichever way you want.
I want to do a loop, normally it is done with while do for etc but when the process is big I came up with a solution to refresh the page by echoing a javascript to refresh the page for the next loop.
for example:
The page is http://localhost/index.php --> this preforms the first iteration with $i=1;
at the end of the script it will be redirected to http://localhost/index.php?i=$i++
if (!$_GET['i']){
$i = 1;
}else{
$i = $_GET['i'];
}
if ($i<500){
// proceed with $i = $_GET['i']
//then redirect to http://localhost/index.php?i=$i++
}else{
echo "done";
}
Now, consider a situation that the imput parameters come from a FORM to this script. (i.e. $parameter1 , $parameter2, $parameter3)
Then I have to pass them every time to new url (next iteration).
At normal work I can pass them as GET variable to new url but how can I pass them if I don't want the user be able to see the value of parameters in url?
At normal work I can pass them as GET variable to new url but how can I pass them if I don't want the user be able to see the value of parameters in url?
You can not with the bare redirect, but if you're talking about a specific user, you can do so by assigning those parameters as session variables Docs and then passing the session id as an additional parameter (or trust the user has cookies enabled).
function do_redirect($i, Array $parameters)
{
$i = (int) $i;
$parameters['i'] = $i; // save to session as well
$_SESSION['parameters'] = $parameters;
// redirect to http://localhost/index.php?i=$i&SID
}
if (is_form_request())
{
$parameters = get_form_parameters();
do_redirect(1, $parameters);
}
elseif (is_redirect_loop_request())
{
$parameters = $_SESSION['parameters'];
$i = $parameters['i'];
if ($i < 500)
{
do_redirect($i++, $parameters);
} else {
echo "done.";
}
}
Not to be rude, but both answers above are quite prone to security issues (but the session solution is the best one). As for the 'encryption' solution of #itamar: that's not exactly encryption... This is called 'Caesar cypher' (http://en.wikipedia.org/wiki/Caesar_cipher), which is indeed as safe as a paper nuclear bunker...
It can be much easier and safe as can be; do not save the iteration in the session, but in the database. For the next request, the only thing you have to do is get the iterator from the database and go on with whatever you want to do. Sessions can be stolen, meaning someone could let you iterate from, say, $i=10 a thousand times. It cannot be done when the iterator is stored in a secure database.