Problem
Hey, my array $isActiefErr and $naamErr doesn't fill up after I throw an exception, but the foreach loop does continue to validate the values. I know the foreach loop keeps on looping, because the array which should have all the values is filled, but the error array stops after it encounters its first error.
What I have tried:
I've tried to print the array but it only pushes the first error into my array. It then stops validating. This also shows in my error log. I think the problem would be the try/catch, but I simply cannot confirm this, because of my lack of knowledge regarding try/catches.
Question
How can I get the array to push and display all the errors with a try/catch block surrounding it? Or am I simply missing something and isn't the problem related to the try/catch?
This is my code:
$validateOk = 0;
$setVar = new SetVariable();
$teller = 1;
$save = null;
$validateOk = 0;
$con->beginTransaction();
$weg = TypeQuery::create()->find();
$weg->delete();
try {
foreach ($_POST as $key => $value) {
if (isEven($teller)) {
$validateOk += $setVar->nameval($key)
->onerror($isActiefErr[]) //errors aren't being pushed into this array, besides the first one.
->validator(v::numericVal())
->go();
if ($validateOk == 0) {
$save->setCode(substr($key, 1));
$save->setIsActief($value);
$save->save();
} else {
//ROLLBACK/CATCH
throw new Exception($error);
}
} else {
$validateOk += $setVar->nameval($key)
->onerror($naamErr[])
->validator(v::alpha('/()éá&., '))
->go();
if ($validateOk == 0) {
$save = new Type();
$save->setCode(substr($key, 1));
$save->setNaam($value);
} else {
//ROLLBACK/CATCH
throw new Exception($error);
}
}
$teller += 1;
}
$con->commit();
} catch (Exception $e) {
$error = "Het opslaan is fout gegaan!";
} {
$con->rollback();
}
Related
I have this transaction and try catch statement that checks the value of each $_POST['count'] is not less than 0. *the rollback only happens when the if statement is false it doesn't include the past update which is incorrect
$this->db->trans_begin();
foreach($_POST['ID'] as $val => $r)
{
//Gets Count
$this->db->select('count');
$this->db->from('table1');
$this->db->where('table_id', $r);
$oc = $this->db->get()->row('count');
$nc = (($oc) - $_POST['count'][$val]);
//Gets Total
$this->db->select('cost');
$this->db->from('table1');
$this->db->where('table_id', $r);
$ot = $this->db->get()->row('cost');
$total = ($ot + $total);
try{
if($nc > 0){
//Updates Quantity
$process = array(
'current_count' => $nc,
);
$this->db->where('product_id', $rm);
$this->db->update('products', $process);
}
}
catch(Exception $e){
$this->db->trans_rollback();
$this->session->set_flashdata('error','Production Failed. 1 or more Raw Materials required for production is insufficient.');
exit;
}
}
$this->db->trans_commit();
there are insert and update statements afterwards but what i want is to stop the whole process if an exception is caught apparently the exit; statement doesn't do so
There are a several ways to do this. Perhaps the easiest is this.
Model:
//I'm making the function up cause you don't show it
public function do_something(){
//all code the same up to here...
if($nc > 0){
//Updates Count
$process = array('count' => $nc);
$this->db->where('table_id', $r);
$this->db->update('table1', $process);
} else {
$this->db->trans_rollback();
throw new Exception('Model whats_its_name has nothing to process');
}
The catch statement in the model will catch any exception that the database class(es) might throw. (Do they throw any exceptions? I don't know.)
Controller
try{
$this->some_model->do_something();
}
catch (Exception $e) {
//catch the exception thrown in do_something()
//additional handling here
}
All that said, it might be wise to check $_POST['count'] for the appropriate values before you call $this->some_model->do_something();
I am trying to add a product to my shopping cart.
I am getting an error saying:
Warning: Invalid argument supplied for foreach() in
It is telling me I am getting an error for the following code:
function isInCart($id) {
if (!empty($_SESSION['sess_uid']['cart'])) {
foreach ($_SESSION['sess_uid']['cart'] as $report) {
if ($report['reportID'] == $id) {
// Report ID found in Cart
return true;
}
}
// Looped through cart, ID not found
return false;
} else {
// Cart empty
return false;
}
}
The particular line from the above that is flagging the error is:
foreach ($_SESSION['sess_uid']['cart'] as $report) {
I am also getting the following error message:
Fatal error: Only variables can be passed by reference in
The code this relates to is the following:
function addToCart($id) {
$report = getReportByID($id);
$author = $report['userID'];
if (!empty($report)) {
// Got the report
if (!empty($_SESSION['sess_uid']['cart'])) {
if (!isInCart($id) && !isOwner($author) && !hasPurchased($id)) {
array_push($_SESSION['sess_uid']['cart'], $report);
return true;
} else {
return false;
}
} else {
$_SESSION['sess_uid']['cart'] = array();
if (!isInCart($id) && !isOwner($author) && !hasPurchased($id)) {
array_push($_SESSION['sess_uid']['cart'], $report);
return true;
} else {
return false;
}
}
} else {
// Unable to get report by ID
return false;
}
}
The particular line of code from the above that is flagging the error is:
array_push($_SESSION['sess_uid']['cart'], $report);
The code below is what gets my reports to populate the store
<?php
function getReportByID($id) {
$conn = new mysqli(localhost, root, DBPASS, DBNAME);
$sql = "SELECT * FROM reports WHERE reportID = '" . $conn->real_escape_string($id)."';";
// Performs the $sql query on the server
$report = $conn->query($sql);
return $report->fetch_array(MYSQLI_ASSOC);
}
?>
Any help would be greatly appreciated.
Thanks
i think this wil help:
it typcast your session as an array so even when the session is empty you dont get an error
foreach ((array)$_SESSION['sess_uid']['cart'] as $report) {
let me know if this fix the error?
The php manual states under 'Changelog for break':
5.4.0 Removed the ability to pass in variables (e.g., $num = 2; break $num;) as the numerical argument.
I have a function that copies a table with a tree structure to another table.
After copying each record, the function tests a relation to see if that record has more child records in the next "level" of the tree.
If child records are found, this same function is executed for each child record using a foreach() loop. If they also have child records, the process is repeated, etc. etc.
So the number of "branches" and "levels" in the table will determine how many foreach() loops will be executed. Since the user creates the records, I have no control over the number of "branches" and "levels" in the table.
If break cannot receive a variable any more (I cannot run "branch" and "level" counters any more) - how do you break out of ALL loops if an error occurs?
Scaled down example:
public function copyTreeModels($row, $id)
{
try
{
/* copy current record. */
$status == 'ok';
/* loop to this same function if $status == 'ok' and hasChildren */
if($status == 'ok')
{
If ($row['hasChildren'] == 'yes') // check relation
{
foreach($row['children'] as $child)
{
$this->copyTreeModels($child, $id);
}
}
}
else
{
// break;
throw new CDbException($message);
}
}
catch(CDbException $e)
{
$message .= $e->getMessage();
}
return($message);
}
Don't put try in the recursive function. You need a wrapper function around the whole thing that establishes the condition handler:
public function copyTreeModels($row, $id) {
try {
$this->copytreeModelsRecurse($row, $id);
}
catch(CDbException $e)
{
$message .= $e->getMessage();
}
return($message);
}
copyTreeModelsRecurse would then be your copyTreeModels function, but without the try/catch blocks.
The only thing I can think of is to set a variable which determines whether or not to break all.
An example (untested) is
$break_all = false;
foreach($values as $val) {
foreach($val as $val1) {
foreach($val1 as $val2) {
if($val2 == "xyz") {
$break_all = true;
}
if($break_all) break;
}
if($break_all) break;
}
if($break_all) break;
}
I'll agree with the fact it's not a pretty solution however.
Edit:
An alternative suggestion if the amount of nested loops to break; from is a variable amount is setting a counter and decrementing the break counter for each break, and only breaking if it is greater than 0:
$break_count = 0;
foreach($values as $val) {
foreach($val as $val1) {
foreach($val1 as $val2) {
if($val2 == "xyz") {
$break_count = 3;
}
if($break_count > 0) { $break_count--; break; }
}
if($break_count > 0) { $break_count--; break; }
}
if($break_count > 0) { $break_count--; break; }
}
My foreach loop:
$empty = "You cannot decommission this truck. It is in use."
$msg = "";
foreach ($trucks_to_remove as $truck_id) {
$truck_id = trim($truck_id);
if (strlen($truck_id)) {
$msg .= decom_truck(
$db,
$depot_id,
$truck_id
);
}
else
{
echo $empty;
}
}
echo $msg;
If the condition is not met, it means the sql cursor that preceded this foreach loop did not return a result for this truck_id (meaning it is in use), I just want a simple message sent to the page to alert the user.
It does not have to be a pop-up or the like. Where would I put my write or print statement? I assume I'd use an else clause but when I add an else inside the foreach loop (see above), I get nothing printed to the page. I have also tried the following:
else if (strlen($truck_id)) == 0
{
echo $empty;
}
I am very new to php.
$arr1 = array();
if(!$arr1)
{
echo 'arr1 is emty<br/>';
$arr2 = array(1, 2);
if($arr2)
echo 'arr2 has data';
exit();
}
I have this code to retrieve some countervalues of a copymachine.
foreach($sett as $key => $value){
if (intval(str_replace("INTEGER: ","",snmpget($ip, "public", $base.$value["MIB"])))) {
$c = intval(str_replace("INTEGER: ","",snmpget($ip, "public", $base.$value["MIB"])));
$error = false;
}
else {
$c = 0;
$error = true;
}
$counters = array_push_assoc($counters,ucwords($key),array("total" => $c, "code" => $value["code"]));
}
everything works like a charm but the only thing that is the problem is when a machine is down en the code cannot make an SNMPGET, the whole script fails.
First I want to check if the connection to the device is alive and then retrieve the counters with SNMPGET
Is there any solution you guys can offer me?
thx
The snmpget() function returns FALSE if it fails to retrieve the object.
See docs: http://www.php.net/manual/en/function.snmpget.php
You should do a check for this within your code, for example:
try
{
foreach($sett as $key => $value){
$sntpReturn = snmpget($ip, "public", $base.$value["MIB"]);
if ($sntpReturn === false)
{
// Do something to handle failed SNTP request.
throw new Exception("Failed to execute the SNTP request to the machine.");
}
else
{
if (intval(str_replace("INTEGER: ","", $sntpReturn))) {
$c = intval(str_replace("INTEGER: ","",snmpget($ip, "public", $base.$value["MIB"])));
$error = false;
}
else {
$c = 0;
$error = true;
}
$counters = array_push_assoc($counters,ucwords($key),array("total" => $c, "code" => $value["code"]));
}
}
catch (Exception $e)
{
// Handle the exception, maybe kill the script because it failed?
}