I'm using the following code to validate a 'set' of input fields. 4 fields per set (width/height/length/weight). If a set of my input fields are empty then it won't display that row of data in my final $all variable.
Here is a previous topic on the subject: Removing Data from Variable if Input Fields incomplete - PHP - this works great.
However, this time I am using "Placeholder" text (input field value attribute) and therefore I need my PHP to check whether that placeholder value exists.
Here is my Pseudo Code, however I'm unsure how to achieve with regular PHP:
if ((pNUM-VALUEheight = "Height (cm)" OR pNUM-VALUEwidth = "Width (cm)" OR pNUM-VALUElength = "Length (cm)" OR pNUM-VALUEweight = "Weight (kg)"))
Then
// Don't store in $all variable
Else
// Do store set of values in $all variable
End If
Here is my current PHP code:
...
$ierrors = array();
$all = '';
// Loop over the values 1 through 20
foreach( range( 1, 20) as $i)
{
// Create an array that stores all of the values for the current number
$values = array(
'p' . $i . 'height' => $_POST['p' . $i . 'height'],
'p' . $i . 'width' => $_POST['p' . $i . 'width'],
'p' . $i . 'length' => $_POST['p' . $i . 'length'],
'p' . $i . 'weight' => $_POST['p' . $i . 'weight']
);
// Assume all values are empty.
$allEmpty = true;
// Validate every value
foreach( $values as $key => $value)
{
if( empty($value))
$ierrors[] = "Value $key is not set";
else
$allEmpty = false;
// You can add more validation in here, such as:
if( !is_numeric( $value) )
$ierrors[] = "Value $key contains an invalid value '$value'";
}
// Join all of the values together to produce the desired output
if (!$allEmpty)
$all .= implode( '|', $values) . "\n\n";
}
...
Many thanks for any pointers here or please let me know if any clarity is needed.
Thank you
As you're using jQuery, I'd use a bit of JavaScript to clear the input fields on submit:
$('form').submit(function() {
$(this).find('input[type=text]').each(function() {
var domElement = $(this).get(0);
if (domElement.value == domElement.defaultValue) {
domElement.value = '';
}
});
});
Watch out for typos, didn't test.
You can then check in your PHP file for empty strings and don't have to explicitly state all the possible values (they might change slightly, after all):
if ($_POST['inputName'] == '')
OR
you could use a simple for loop:
for ($i = 0, $numFields = 20; $i <= $numFields; ++$i) {
if ($_POST['p' . $i . 'width'] != 'Width (cm)' && $_POST['p' . $i . 'height'] != 'Height (cm)') {
// add row to table
}
}
What about doing something like this with your HTML:
<input type="text" name="length[]">
<input type="text" name="width[]">
Then you can do something like this in PHP:
if(array_keys($_POST['length']) != array_keys($_POST['width']))
{
// Incomplete post
}
$all_keys = array_merge(array_keys($_POST['length']), array_keys($_POST['width']));
foreach($all_keys as $curr_key)
{
// $_POST['length'][$curr_key]
// $_POST['width'][$curr_key]
}
While using JS is good to validate information from the client before submission. You should always check your values server side as well.
Related
I was given to fill this html table according to this multidimensional array.
$eleves=array(
"Z200"=>array(
"Salima",
"module"=>array(
"Math"=>array("note"=>10,"cof"=>5),
"Physique"=>array("note"=>10,"cof"=>2),
"Langue"=>array("note"=>10,"cof"=>2)
)
),
"Z103"=>array(
"Ali",
"module"=>array(
"Math"=>array("note"=>2,"cof"=>5),
"Physique"=>array("note"=>5,"cof"=>2),
"Langue"=>array("note"=>7,"cof"=>2)
)
),
"Z109"=>array(
"Hind",
"module"=>array(
"Math"=>array("note"=>13,"cof"=>2),
"Physique"=>array("note"=>13,"cof"=>2),
"Langue"=>array("note"=>11# ,"cof"=>2)
)
)
);
I tried the foreach loop. I succeed to fill the first head tables.
But when it comes to calculate the notes it's diffcult to call the values
Can you help me guys please ?
You need a first foreach to browse $eleves. For each student, you need a second foreach to add all grades and evaluate the mean.
function evalMoyenne ($grades) {
$gradeSum = 0;
$coeffCount = 0;
foreach ( $grades as $subject => $grade ) {
$gradeSum += $grade['note'] * $grade['cof'];
$coeffCount += $grade['cof'];
}
return $gradeSum / $coeffCount;
}
foreach ( $eleves as $matricule => $row ) {
$moyenne = evalMoyenne( $row['module'] );
echo "<td>$matricule</td>"
. '<td>' . $row[0] . '</td>'
. '<td>' . $moyenne . '</td>'
}
Usually, if you have an array in an array, you need a foreach in a foreach. As an alternative, if there are a fixed subject count, you could also hardcode the meaning calculation:
$gradeSum = $row['module']['Math']['note'] * $row['module']['Math']['cof']
+ $row['module']['Physique']['note'] * $row['module']['Physique']['cof']
+ $row['module']['Langue']['note'] * $row['module']['Langue']['cof']
$cofSum = $row['module']['Math']['cof'] + $row['module']['Physique']['cof'] + $row['module']['Langue']['cof'];
$moyenne = $gradeSum / $cofSum;
I'm currently updating the database with selected values, however, I am using a for loop to process for each entry. But I can only do this to a select number, currently 6 as shown below.
for ($ind = 0; $ind <6; $ind++ )
How would I make it loop through all & then stop?
I'm currently getting the values from another page using $_POST & then submitting them to the database on this page. As shown below:
for ($ind = 0; $ind <6; $ind++ ) {
$SID = $_POST['SID' . $ind];
$week1 = $_POST ['week1' . $ind];
$week2 = $_POST ['week2' . $ind];
$week3 = $_POST ['week3' . $ind];
$week4 = $_POST ['week4' . $ind];
$week5 = $_POST ['week5' . $ind];
$week6 = $_POST ['week6' . $ind];
$week7 = $_POST ['week7' . $ind];
$week8 = $_POST ['week8' . $ind];
$week9 = $_POST ['week9' . $ind];
$week10 = $_POST ['week10' . $ind];
$sqlQuery = "Update weekbyweek SET Week_1=".$week1.", Week_2=".$week2.", Week_3=".$week3.", Week_4=".$week4.", Week_5=".$week5.", Week_6=".$week6.", Week_7=".$week7.", Week_8=".$week8.", Week_9=".$week9.", Week_10=".$week10." WHERE SID='".$SID."'";
$statement = $db->prepare($sqlQuery);
$statement->execute(['$Week_1' => $week1, '$Week_2' => $week2,'$Week_3' => $week3, '$Week_4' => $week4,'$Week_5' => $week5, '$Week_6' => $week6,'$Week_7' => $week7, '$Week_8' => $week8,'$Week_9' => $week9, '$Week_10' => $week10]);
}
Use foreach loop instead of for. The foreach loop is mainly used for looping through the values of an array.
<?php
foreach (array as $value) {
// Code to be executed;
}
You can set a count that will check the length of your data array.
Below will loop 8 times and then stop.
In below case the data is an array. If working with databaseso you would have to query the database for the X amount setting that you would need, stored the result in a variable and set the count to that variable value.
$data = [0,1,2,3,4,5,6,7];
for ($i=0; $i <= count($data) ; $i++) {
// code...
}
Use this:
$items = [1,2,3,4,5,6,7];
if( !empty( $items ) ){
for ( $i=0; $i < count( $items ) ; $i++ ) {
//code here
}
}
Or
foreach( $items as $item ){
//code here
}
I am developing a database-driven website using Laravel. Now I am having a problem with updating database. I want to run bulk update. Normally I run like this.
$data = [
[
'col_1'=>$value1
],
[
'col_1'=>$value2
],
[
'col_1'=>$value3
],
[
'col_1'=>$value4
]
];
MyTableObject::update($data)->where('col_2'=>$col_2_val);
As you can see in the above code, where clause is checking for only one condition for all rows that are to be updated. But what I want is that I want the different where clause condition for each row or query. To use foreach and run query for each row, it will be time-consuming because I have to update a lot of rows. To demonstrate it, it will be something like this.
$data = [
[
'col_1'=>$value1,
'col_2'=>$where_value_1 // This is not the column to be updated. That is for where clause.
],
[
'col_1'=>$value2,
'col_2'=>$where_value_2 // This is not the column to be updated. That is for where clause.
],
[
'col_1'=>$value3,
'col_2'=>$where_value_3
],
[
'col_1'=>$value4,
'col_2'=>$where_value_4
]
];
MyTableObject::update($data)->where('where_col_name'=>'col_2');
I found this link, but the answers are not clear and complete. Is it possible to do it in Laravel, and how can I do it?
If I'm understanding this correctly, col_1 is the value you wish to use in update and col_2 is the value you're querying against. Try the following (may need some adjustments)
collect($data)->each(function(array $row) {
MyTableObject::where('where_col_name', $row['col_2'])->update(['col_1' => $row['col_1']]);
});
Here is the batch update function which I wrote to use in my Laravel projects. Its first parameter is the table name string, second is the key name string on which you want to update the row or rows and mostly it will be the 'id', the third parameter is the data array in the format:
array(
array(
'id' => 1,
'col_1_name' => 'col_1_val',
'col_2_name' => 'col_2_val',
//.....
),
array(
'id' => 2,
'col_1_name' => 'col_1_val',
'col_2_name' => 'col_2_val',
//.....
),
//.....
);
Function:
private function custom_batch_update(string $table_name = '', string $key = '', Array $update_arr = array()) {
if(!$table_name || !$key || !$update_arr){
return false;
}
$update_keys = array_keys($update_arr[0]);
$update_keys_count = count($update_keys);
for ($i = 0; $i < $update_keys_count; $i++) {
$key_name = $update_keys[$i];
if($key === $key_name){
continue;
}
$when_{$key_name} = $key_name . ' = CASE';
}
$length = count($update_arr);
$index = 0;
$query_str = 'UPDATE ' . $table_name . ' SET ';
$when_str = '';
$where_str = ' WHERE ' . $key . ' IN(';
while ($index < $length) {
$when_str = " WHEN $key = '{$update_arr[$index][$key]}' THEN";
$where_str .= "'{$update_arr[$index][$key]}',";
for ($i = 0; $i < $update_keys_count; $i++) {
$key_name = $update_keys[$i];
if($key === $key_name){
continue;
}
$when_{$key_name} .= $when_str . " '{$update_arr[$index][$key_name]}'";
}
$index++;
}
for ($i = 0; $i < $update_keys_count; $i++) {
$key_name = $update_keys[$i];
if($key === $key_name){
continue;
}
$when_{$key_name} .= ' ELSE ' . $key_name . ' END, ';
$query_str .= $when_{$key_name};
}
$query_str = rtrim($query_str, ', ');
$where_str = rtrim($where_str, ',') . ')';
$query_str .= $where_str;
$affected = DB::update($query_str);
return $affected;
}
It will produce and execute the query string like this:
UPDATE table_name SET col_1_name = CASE
WHEN id = '1' THEN 'col_1_value'
WHEN id = '2' THEN 'col_1_value'
ELSE col_1_name END,
col_2_name = CASE
WHEN id = '1' THEN 'col_2_value'
WHEN id = '2' THEN 'col_2_value'
ELSE col_2_name END
WHERE id IN('1','2')
I am trying to make a query where I want to retrieve items querying a field in the database.
I need to check something as follows (example):
To retrieve books where the text field contain "Soccer" or "Basketball":
I want to have the items where only in the population above:
contain '1989'
and
exclude 'Europe'
Any idea? I am doing a counting for now but it does not work:
//search words
foreach ($cardSearch as $value) {
$regexSearch[]['text'] = new MongoRegex("/" . $value . "/");
}
//words included
foreach ($cardInclu as $value) {
$regexInclu[]['text'] = new MongoRegex("/" . $value . "/");
}
//words excluded
foreach ($cardExlu as $value) {
$regexExclu[]['text'] = new MongoRegex("/" . $value . "/");
}
$arr['$and'] = $regexInclu;
$arr['$ne'] = $regexExclu;
array_push($regexSearch, $arr);
$i = $mongoCollection->count(array('$or' => $regexSearch));
or
$i = $mongoCollection->count(array('$or' => $regexSearch,
'$and' => $regexInclu, '$ne' => $regexExclu));
Thanks!
Suppose I have a multi-dimensional array of the form:
array
(
array('Set_ID' => 1, 'Item_ID' => 17, 'Item_Name' = 'Whatever'),
array('Set_ID' => 1, 'Item_ID' => 18, 'Item_Name' = 'Blah'),
array('Set_ID' => 2, 'Item_ID' => 19, 'Item_Name' = 'Yo')
)
The array has more sub-arrays, but that's the basic form-- Items in Sets.
How can I loop through this array so that I can echo the number of items in each set along with the all the items like so:
Set 1 has 2 Items: 17: Whatever and 18: Blah
Set 2 has 1 Items: 19: Yo
I'm aware that this could be done with two loops-- one to build an array, and another to loop through that array. However, I'd like to do this all with only one loop.
In your answer, you should assume that there are two display functions
display_set($id, $count) //echo's "Set $id has $count Items"
display_item($id, $name) //echo's "$id: $name"
UPDATE: Forgot to mention that the data is sorted by Set_ID because its from SQL
Right, all the examples below rely on an ordered set, the OP states it is ordered initially, but if needed a sort function could be:
// Sort set in to order
usort($displaySet,
create_function('$a,$b',
'return ($a['Set_ID'] == $b['Set_ID']
? ($a['Set_ID'] == $b['Item_ID']
? 0
: ($a['Item_ID'] < $b['Item_ID']
? -1
: 1))
: ($a['Set_ID'] < $b['Set_ID'] ? -1 : 1));'));
Straight example using a single loop:
// Initialise for the first set
$cSetID = $displaySet[0]['Set_ID'];
$cSetEntries = array();
foreach ($displaySet as $cItem) {
if ($cSetID !== $cItem['Set_ID']) {
// A new set has been seen, display old set
display_set($cSetID, count($cSetEntries));
echo ": " . implode(" and ", $cSetEntries) . "\n";
$cSetID = $cItem['Set_ID'];
$cSetEntries = array();
}
// Store item display for later
ob_start();
display_item($cItem['Item_ID'], $cItem['Item_Name');
$cSetEntries[] = ob_get_clean();
}
// Perform last set display
display_set($cSetID, count($cSetEntries));
echo ": " . implode(" and ", $cSetEntries) . "\n";
Using a recursive function it could be something like this:
// Define recursive display function
function displayItemList($itemList) {
if (!empty($itemList)) {
$cItem = array_shift($itemList);
display_item($cItem['Item_ID'], $cItem['Item_Name');
if (!empty($itemList)) {
echo " and ";
}
}
displayItemList($itemList);
}
// Initialise for the first set
$cSetID = $displaySet[0]['Set_ID'];
$cSetEntries = array();
foreach ($displaySet as $cItem) {
if ($cSetID !== $cItem['Set_ID']) {
// A new set has been seen, display old set
display_set($cSetID, count($cSetEntries));
echo ": ";
displayItemList($cSetEntries);
echo "\n";
$cSetID = $cItem['Set_ID'];
$cSetEntries = array();
}
// Store item for later
$cSetEntries[] = $cItem;
}
// Perform last set display
display_set($cSetID, count($cSetEntries));
echo ": ";
displayItemList($cSetEntries);
echo "\n";
Amusingly, it can be one single recursive function:
function displaySetList($setList, $itemList = NULL) {
// First call, start process
if ($itemList === NULL) {
$itemList = array(array_shift($setList));
displaySetList($setList, $itemList);
return;
}
// Check for display item list mode
if ($setList === false) {
// Output first entry in the list
$cItem = array_shift($itemList);
display_item($cItem['Item_ID'], $cItem['Item_Name']);
if (!empty($itemList)) {
// Output the next
echo " and ";
displaySetList(false, $itemList);
} else {
echo "\n";
}
return;
}
if (empty($setList) || $setList[0]['Set_ID'] != $itemList[0]['Set_ID']) {
// New Set detected, output set
display_set($itemList[0]['Set_ID'], count($itemList));
echo ": ";
displaySetList(false, $itemList);
$itemList = array();
}
// Add next item and carry on
$itemList[] = array_shift($setList);
displaySetList($setList, $itemList);
}
// Execute the function
displaySetList($displaySet);
Note that the recursive example here is grossly inefficient, a double loop is by far the quickest.
<?php
$sets = array();
foreach ($items as $item)
{
if (!array_key_exists($item['Set_ID'], $sets))
{
$sets[$item['Set_ID']] = array();
}
$sets[$item['Set_ID']][] = $item;
}
foreach ($sets as $setID => $items)
{
echo 'Set ' . $setID . ' has ' . count($items) . ' Items: ';
foreach ($items as $item)
{
echo $item['Item_ID'] . ' ' . $item['Item_Name'];
}
}
?>
Something like this i guess?
EDIT:
After i posted this i saw the display functions where added. But you get the point.
The need to not print out any items until we know how many there are in the set makes this difficult. At some point, we'll need to doing some buffering, or else backtracking. However, if I'm allowed internal loops, and sets are contiguous in the "master" array, then with some hacking around:
$set = 0;
$items;
foreach ($arr as $a) {
if ($a['Set_ID'] != $set) {
if ($set != 0) {
display_set($set, count($items));
foreach ($items as $i)
display_item($i)
}
$set = $a['Set_ID'];
$items = array();
}
$items[] = $a;
}
How about this:
$previous_set = false;
$items = '';
$item_count = 0;
foreach ($rows as $row)
{
if ($row['Set_ID'] != $previous_set)
{
if ($previous_set)
{
echo display_set($row['Set_ID'], $item_count);
echo $items;
}
$previous_class = $row['Set_ID'];
$item_count = 0;
$items = '';
}
$items .= display_item($row['Item_ID'], $row['Title']);
$item_count++;
}
echo display_set($row['Set_ID'], $item_count);
echo $items;