I'm trying to pass variables from a foreach function that fetch a mysql query to an array, to another function.
I declare the array before the foreach to make it global but no data are passed to the function.
here is my code. If you have any idea of what i'm doing, thanks by advance for your help.
Of course if I replace the called function by what's inside it, everything works like a charm.
but as I'll have to use it several times I would prefer to set my variables in a function.
function fillStuInfos() {
global $studFName, $studLName,c$dateStart, $dateEnd;
$studFName = $EventsGt['fName'];
$studLName = $EventsGt['lName'];
$dateStart = $EventsGt['startDate'];
$dateEnd = $EventsGt['endDate'];
}
$email = $_POST['email'];
$EventsGt = array();
$getEventsQry = 'SELECT * FROM Companies WHERE Email_Company = "'.$email.'" ORDER BY startDate';
foreach ($bddPDO->query($getEventsQry) as $EventsGt) {
$intCur = date_diff(date_create($today), date_create($EventsGt['endDate']));
$intFut = date_diff(date_create($today), date_create($EventsGt['startDate']));
echo intval($intCur->format('%r%a'));
if (intval($intCur->format('%r%a')) <= 4 && intval($intCur->format('%r%a')) > 0 ) {
fillStuInfos();
} else if ( intval($intFut->format('%r%a')) <= 4 && intval($intFut->format('%r%a')) > 0 ){
fillStuInfos();
} else {
echo 'No Datas!';
exit();
}
}
echo $studLName;
Forget that exists global and pass params to function.
function fillStuInfos($data) {
$studFName = $data['fName'];
$studLName = $data['lName'];
$dateStart = $data['startDate'];
$dateEnd = $data['endDate'];
}
...
foreach (...) {
if (intval($intCur->format('%r%a')) <= 4 && intval($intCur->format('%r%a')) > 0 ) {
fillStuInfos($EventsGt);
} else if ( intval($intFut->format('%r%a')) <= 4 && intval($intFut->format('%r%a')) > 0 ){
fillStuInfos($EventsGt);
} else {
echo 'No Datas!';
exit();
}
}
Your variable you want to be global is $EventsGt, not $studFName, $studLName, $dateStart, $dateEnd
With that said, I would recommend passing the event array as a parameter or passing the individual values as parameters instead.
Related
I have an array() lenght=13 which I am using in foreach
$games = array(1,2,3,4,5,6,7,8,9,10,11,12,13);
foreach($games as $game_id){
$this->insertTrainingData($game_id, 'advance', 5);
$this->insertTrainingData($game_id, 'intermediate', 4);
$this->insertTrainingData($game_id, 'easy', 3);
}
The above foreach loop passes each game_id into insertTrainingData() for game_id insertion based on certain validations.
insertTrainingData() is validating each game_id before inserting the record, if all goes well then function store game_id for particular group (advance, intermediate, easy).
What is problem that I am facing?
It is when foreach loop passes game_id to three times called insertTrainingData() method in single iteration and jump into next iteration then same process. I am thinking on next iteration foreach loop passes game_id before completion of previous iteration job (insertTrainingData()).
So is this possible if I can stop foreach loop iteration until all functions return final result and then let foreach loop on next iteration. That's what I am thinking, not sure if I am wrong.
Here is function which decides to insert game_id for particular group based on validations.
private function insertTrainingData($game_id, $type, $limit){
$error = 0;
$result = true;
$todayTraining = Training::whereRaw("Date(created_at)=Curdate() and type='".$type."'")->get();
if($todayTraining->count() === $limit ){
$error = 1;
$result = false;
}
$todayExist = Training::whereRaw("Date(created_at)=Curdate() and game_id=$game_id")->get();
if($todayExist->count() > 0 || $todayExist->first() !== null){
$error = 1;
$result = false;
}
$recordInTwoRowDays = Training::whereRaw("created_at >= DATE_ADD(CURDATE(), INTERVAL -1 DAY) and game_id=$game_id and type='".$type."'")->get();
if($recordInTwoRowDays->count() > 0 ){
$error = 1;
$result = false;
}
if($error === 0){
$AddTraining = new Training;
$AddTraining->game_id = $game_id;
$AddTraining->type = $type;
$AddTraining->save();
$result = true;
}
return $result;
}
What happened when I executed above script?
Actually the above script added 6 rows for advance group however you can see the limit is 5
Can someone kindly guide me about it, I would really appreciate.
Thank you so much.
Your code is fine and it should not insert the 6th rows, maybe you are looking on wrong place, however, here is the code that you can improve:
It will not go for other if statement when the first statement is
false
Hence it will not call for second SQL statement
->count() is way much better than ->get()->count()
.
private function insertTrainingData($game_id, $type, $limit) {
$todayTraining = Training::whereRaw("Date(created_at)=Curdate() and type='".$type."'")->count();
if ($todayTraining >= $limit ) {
return false;
}
$todayExist = Training::whereRaw("Date(created_at)=Curdate() and game_id=$game_id")->count();
if ($todayExist > 0) {
return false;
}
$recordInTwoRowDays = Training::whereRaw("created_at >= DATE_ADD(CURDATE(), INTERVAL -1 DAY) and game_id=$game_id and type='".$type."'")->count();
if ($recordInTwoRowDays > 0 ) {
return false;
}
$addTraining = new Training();
$addTraining->game_id = $game_id;
$addTraining->type = $type;
$addTraining->save();
return true;
}
There are three functions. Two of the functions uses some variables exactly the same way so I created a third function but the variables aren't able to be passed into those two functions.
EDIT
What I need in more detail. Two functions are identical search() and report() but of course there will be differences too.
search()
public function search(){
if(($_POST['number'] != null) && (is_numeric($_POST['number']))){
$number = trim($_POST['number']);
}else{
$number = "";
}
if (($_POST['name'] != null)) {
$name = strtoupper(trim($_POST['name']));
}else{
$comments = "";
}
if($_POST['date'] != null){
$date = trim($_POST['date']);
$parseDate = explode("/", $date);
$newDate = $parseDate[2].$parseDate[0].$parseDate[1];
}else{
$newDate = null;
}
//something will be done here//
//will require using all 3 of the variables above
}
report()
public function report(){
if(($_POST['number'] != null) && (is_numeric($_POST['number']))){
$number = trim($_POST['number']);
}else{
$number = "";
}
if (($_POST['name'] != null)) {
$name = strtoupper(trim($_POST['name']));
}else{
$comments = "";
}
if($_POST['date'] != null){
$date = trim($_POST['date']);
$parseDate = explode("/", $date);
$newDate = $parseDate[2].$parseDate[0].$parseDate[1];
}else{
$newDate = null;
}
//something will be done here//
//will require using all 3 of the variables above
}
combine()
public function combine(){
//as can be seen. The above two functions are totally the same but after that where I commented "something will be done here" different things would be done with different output.
}
search() and report() will end up using json_encode to pass some data back to the client side.
I'm trying to find a smarter way to validate my inputs with PHP. If the array finds an empty field, it has to add a new element to the array and display an error message.
So far, I haven't succeeded.
The code behind
$felter = array();
if(isset($_POST['submit'])) {
$produktnavn = $_POST['produktnavn'];
$kategori = $_POST['kategori'];
if( !empty( $felter ) ) {
foreach ($felter as $felt) {
if ($felter == '') {
$fejl = true;
}
}
}
else {
$sql = "UPDATE produkt SET produkt_navn = '$produktnavn', fk_kategori_id = '$kategori' WHERE produkt_id=$id";
mysqli_query($db, $sql);
echo "Produktet blev opdateret";
}
Input form
<input type="text" class="form-control" name="produktnavn" value="<?php echo $produktnavn; ?>">
The code starts with $felter = array(); which initializes an empty array.
Then, without changing the array itself, you're checking for non-emptiness of $felter
if( !empty( $felter ) ) {
foreach ($felter as $felt) {
if ($felter == '') {
$fejl = true;
}
}
}
You're trying to iterate over an array that has not gotten any elements pushed into it. And the logic statement if( !empty ($felter)) will also not work as expected either.
As a test, before the check for !empty, put something in the array with $felter[] = 'Test word'; and then, underneath it... (if you're looking for a non-empty array, the logical checker could be if(count($felter)) { before iterating over the array with foreach ($felter as $felt) { if ($felt == '')
$felter = array();
$felter[] = 'Test word';
if(isset($_POST['submit'])) {
$produktnavn = $_POST['produktnavn'];
$kategori = $_POST['kategori'];
if( count( $felter ) ) {
foreach ($felter as $felt) {
if ($felt == '') {
$fejl = true;
}
}
}
I am trying to get an if statement to dynamically code itself based on user input. So the if statement code is being inserted into a variable ($if_statement_variable), like this:
$if_statement_variable = "if (";
$price = trim($_GET["Price"]);
if (!empty($price)) {
$if_statement_variable .= " $Product->price < $price ";
}
$product_name = trim($_GET["Product_name"]);
if (!empty($product_name)) {
$if_statement_variable .= " && $Product->$product_name == 'product_name_string' ";
}
// plus many more if GET requests
$if_statement_variable .= ") ";
Then results from an XML file will be displayed based on user values submitted and the $if_statement_variable.
$XMLproducts = simplexml_load_file("products.xml");
foreach($XMLproducts->product as $Product) {
echo $if_statement_variable; // Here is where the problem is
{ // opening bracket for $variable_if_statement
echo $Product->$product_name; // products displayed based on if statement code in $if_statement_variable
} //closing bracket for $variable_if_statement
}
The echo $if_statement_variable above correctly displays $price from this variable string, but does NOT display $Product->price. Assuming $price had a value of 1000, the output is if ( == 1000 ). How can I get $Product->price to correctly insert itself into the $if_statement_variable so that it displays the $Product->price values from the XML file?
If you're trying to generate a boolean value dynamically, based on some complicated logic, just assign the true/false value to a variable, (say, $booleanValue) and then do if($booleanValue){}
Something like:
$price = trim($_GET['price']);
$product_name = trim($_GET['Product_name']);
if(!empty($price)){
$booleanValue = ($Product->price < $price);
}
if(!empty($productName)){
$booleanValue = ($booleanValue && $Product->$product_name == 'product_name_string')
}
if($booleanValue){
echo $Product->$product_name;
}
In other words, create a variable to hold the actual boolean value, not a string to hold an expression that will evaluate to a boolean value.
Do not build PHP source as a string. In this case callables are a better solution. A callable is a function inside a variable. In PHP this might be an function name, and array with an object and a method name, an anonymous function or an object implementing invoke.
Here is an example for anonymous functions:
function getCondition($parameters) {
$conditions = [];
if (isset($parameters['Price']) && trim($parameters['Price']) != '') {
$price = trim($parameters['price']);
$conditions[] = function($product) use ($price) {
return $product->price < $price;
}
}
if (isset($parameters['Product_name']) && trim($parameters['Product_name']) != '') {
$productName = trim($parameters['Product_name']);
$conditions[] = function($product) use ($productName) {
return $product->product_name == $productName;
}
}
return function($product) use ($conditions) {
foreach ($conditions as $condition) {
if (!$condition($product)) {
return FALSE;
}
}
return TRUE;
}
}
$condition = getConditon($_GET);
if ($condition($product)) {
...
}
It is important that each function can be called the same way. So if you call the condition function you not need to know, which condition it is. In the example above you can imagine that the getCondition() function can get really complex really fast if you add additional conditions.
If you encapsulate the conditions into classes, the usage becomes more readable:
$condition = new \YourCompany\Product\Conditions\Group(
new \YourCompany\Product\Conditions\PriceMaximum($_GET, 'Price'),
new \YourCompany\Product\Conditions\Name($_GET, 'Product_name')
);
if ($condition($product)) {
...
}
This way you separate the actual condition logic from the from the use. The source of all classes is some more then the anonymous function variant. But you you can put each class in it's own file and use them in any combination you need.
The classes need to implement __invoke().
class Group {
private $_conditions = array();
public function __construct() {
$this->_conditions = func_get_args();
}
public function __invoke($product) {
foreach ($this->_conditions as $condition) {
if (!$condition($product)) {
return FALSE;
}
}
return TRUE;
}
}
class Name {
private $_productName = NULL;
public function __construct($parameters, $name) {
if (isset($parameters[$name]) && trim($parameters[$name]) > 0) {
$this->_productName = trim($parameters[$name]);
}
}
public function __invoke($product) {
return (
NULL === $this->_productName ||
$product->product_name == $this->_productName
);
}
}
class PriceMaximum {
private $_maximum = NULL;
public function __construct($parameters, $name) {
if (isset($parameters[$name]) && trim($parameters[$name]) > 0) {
$this->_maximum = trim($parameters[$name]);
}
}
public function __invoke($product) {
return (
NULL === $this->_maximum ||
$product->price < $this->_maximum
);
}
}
This concept can even be used together with an anonymous function:
$condition = new \YourCompany\Product\Conditions\Group(
new \YourCompany\Product\Conditions\PriceMaximum($_GET, 'Price'),
new \YourCompany\Product\Conditions\Name($_GET, 'Product_name'),
function ($product) {
return $product->category == 'food';
}
);
Like the title says, PHP is really confusing me on a simple if comparison statement that's returning the opposite of what it should be returning. I'm trying to compare 2 datetime's that are first converted to strings:
//Fetched db query, this returns 2012-06-23 16:00:00
$databaseDateTime = strtotime($row['time']);
//This now returns 1340481600
//today's date and time I'm comparing to, this returns 2012-06-22 17:14:46
$todaysDateTime = strtotime(date("Y-m-d H:i:s"));
//this now returns 1340399686
Great, everything works perfect so far. Now here's where things get hairy:
if ($databaseDateTime < $todaysDateTime) { $eventType = 'past'; }
And this returns 'past', which of course it shouldn't. Please tell me I'm missing something. My project kind of depends on this functionality being airtight.
**EDIT***
Thanks guys for taking the time to help me out. Let me post the entire code because a few of you need more context. The request is coming from an IOS5 to my backend code and json is being sent back to the phone.
<?php
//all included files including $link to mysqli_db and function sendResponse()
function getEvents($eventType, $eventArray) {
global $link;
global $result;
global $i;
global $todaysDateTime;
foreach ($eventArray as $key => $value) {
$sqlGetDeal = mysqli_query($link, "SELECT time FROM deals WHERE id='$value' AND active='y' LIMIT 1") or die ("Sorry there has been an error!");
while ($row = mysqli_fetch_array($sqlGetDeal)) {
//compare times to check if event already happened
$databaseDateTime = strtotime($row['time']);
if ($databaseDateTime < $todaysDateTime) { $eventType = 'past'; }
$result[$i] = array(
'whenDeal' => $eventType,
'time' => $databaseDateTime,
);
$i++;
}//end while
}//end foreach
}
if (isset($_GET['my'])) {
//$_GET['my'] comes in as a string of numbers separated by commas e.g. 3,2,6,3
$myDeals = preg_replace('#[^0-9,]#', '', $_GET['my']);
$todaysDateTime = strtotime(date("Y-m-d H:i:s"));
$result = array();
$kaboomMy = explode(",", $myDeals);
$i = 1;
if ($myEvents != "") {
getEvents('future', $kaboomMy);
}//end if
sendResponse(200, json_encode($result));
} else {
sendResponse(400, 'Invalid request');
} //end $_POST isset
?>
Found a quick hack around the issue. I just added a local variable to my function and rearranged my compare statement
//added local variable $eventTyppe to function
$eventTyppe;
changed compare from:
if ($databaseDateTime < $todaysDateTime) { $eventType = 'past'; }
to:
if ($todaysDateTime < $databaseDateTime ) {
$eventTyppe = $eventType;
} else {
$eventTyppe = 'past';
}
Notice if I rearrange compare:
if ($databaseDateTime < $todaysDateTime ) {
$eventTyppe = 'past';
} else {
$eventTyppe = $eventType;
}
I still get the same error. This is the weirdest thing I've ever seen and the first PHP bug I've run into (I'm assuming it's a PHP bug).
Could you print the values of the times right before this line?
if ($databaseDateTime < $todaysDateTime) { $eventType = 'past'; }
Since that one is declared as global I'm wondering if is it coming back incorrectly.