Form _POST array problem - php

I have the following code:
if ( (isset($_GET['slAction'])) && ($_GET['slAction'] == "manage_label") )
{
$formData = getFormData();
foreach ($formData as $key => $value)
echo "(Key: $key, Value: $value )<br /> ";
}
// All form fields are identified by '[id]_[name]', where 'id' is the
// identifier of the form type. Eg. label, store etc.
// The field identifier we want to return is just the name and not the id.
function getFormData()
{
$form_fields = array_keys($_POST);
for ($i = 0; $i < sizeof($form_fields); $i++)
{
$thisField = $form_fields[$i];
$thisValue = $_POST[$thisField];
//If field is an array, put all it's values into one string
if (is_array($thisValue))
{
for ($j = 0; $j < sizeof($thisValue); $j++)
{
$str .= "$thisValue[$j],";
}
// Remove the extra ',' at the end
$thisValue = substr($str, 0, -1);
//Assosiative array $variable[key] = value
$formData[end(explode("_", $thisField))] = $thisValue;
}
else
$formData[end(explode("_", $thisField))] = $thisValue;
}
return $formData;
}
The output from this code is:
(Key: id, Value: 7276 )
(Key: name, Value: 911 Main brand )
(Key: email, Value: )
(Key: www, Value: )
(Key: categories, Value: Menswear,Womenswear,Shoes )
(Key: targetgroup, Value: )
(Key: keywords, Value: )
(Key: description, Value: Testing )
(Key: saveForm, Value: Save )
Now this is my problem. The form field called 'label_categories' are checkboxes and is returned as an array. The output, as you see, is "Menswear,Womenswear,Shoes".
If I try 'echo $formData['name']', the output is "911 Main brand".
If I try 'echo $formData['categories']. the output is blank / empty.
How come I can output the string 'name' and not the string 'categories'? In the getFormData() function, I turn the array into a string....
Any help appreciated.

That code can be greatly simplified:
// 1. no need for isset() check in the case where you're testing a value
// 2. use single quotes for strings where possible
if ($_GET['slAction'] == 'manage_label') {
$formData = getFormData();
// 3. Good rule is to use braces even when not necessary
foreach ($formData as $key => $value) {
echo "(Key: $key, Value: $value )<br /> ";
}
}
function getFormData() {
// 4. prefer explicit initialization
$formData = array();
// 5. this foreach is much cleaner than a loop over keys
foreach ($_POST as $k => $v) {
// 6. this is a lot cleaner than end(explode(...))
$name = preg_replace('!.*_!', '', $k);
if (is_array($v)) {
// 7. this implode() replaces 5 lines of code
// and is MUCH clearer to read
$formData[$name] = implode(',', $v);
} else {
$formData[$name] = $v;
}
}
return $formData;
}

instead of posting code, ill explain.
you cannot echo $_post['catagories'] because it is not a string or number. It is an array.
you can echo $_post['catagories'][nth number'] or echo implode(', ' $_post['catagories'])

Related

how to split string and add additional strin to it

i have a string and i need to add some html tag at certain index of the string.
$comment_text = 'neethu and Dilnaz Patel  check this'
Array ( [start_index_key] => 0 [string_length] => 6 )
Array ( [start_index_key] => 11 [string_length] => 12 )
i need to split at start index key with long mentioned in string_length
expected final output is
$formattedText = '<span>#neethu</span> and <span>#Dilnaz Patel</span>  check this'
what should i do?
This is a very strict method that will break at the first change.
Do you have control over the creation of the string? If so, you can create a string with placeholders and fill the values.
Even though you can do this with regex:
$pattern = '/(.+[^ ])\s+and (.+[^ ])\s+check this/i';
$string = 'neehu and Dilnaz Patel check this';
$replace = preg_replace($pattern, '<b>#$\1</b> and <b>#$\2</b> check this', $string);
But this is still a very rigid solution.
If you can try creating a string with placeholders for the names. this will be much easier to manage and change in the future.
<?php
function my_replace($string,$array_break)
{
$break_open = array();
$break_close = array();
$start = 0;
foreach($array_break as $key => $val)
{
// for tag <span>
if($key % 2 == 0)
{
$start = $val;
$break_open[] = $val;
}
else
{
// for tag </span>
$break_close[] = $start + $val;
}
}
$result = array();
for($i=0;$i<strlen($string);$i++)
{
$current_char = $string[$i];
if(in_array($i,$break_open))
{
$result[] = "<span>".$current_char;
}
else if(in_array($i,$break_close))
{
$result[] = $current_char."</span>";
}
else
{
$result[] = $current_char;
}
}
return implode("",$result);
}
$comment_text = 'neethu and Dilnaz Patel check this';
$my_result = my_replace($comment_text,array(0,6,11,12));
var_dump($my_result);
Explaination:
Create array parameter with: The even index (0,2,4,6,8,...) would be start_index_key and The odd index (1,3,5,7,9,...) would be string_length
read every break point , and store it in $break_open and $break_close
create array $result for result.
Loop your string, add , add or dont add spann with break_point
Result:
string '<span>neethu </span>and <span>Dilnaz Patel </span> check this' (length=61)

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
}

get values from multidimensional array

I have a script that creates an array in the following format
$named_array["vehicles"][0]['vehicle'] = "i100-1 " ;
$named_array["vehicles"][1]['vehicle'] = "i100-2 " ;
$named_array["vehicles"][2]['vehicle'] = "i100-46 " ;
What I want to do later in the script is get the index value[0-1-2 etc] from $named_array
but I only have the value ( i100-1 etc) as a query option , This is so I can alter it later. What I want to achieve is something like , what is the index value of $named_array where value is i100-2
this is output to json at the end .
I hope this makes sense ! any help please ?
function complex_index_of($named_array, $val){
for($i=0, $n=count($named_array['vehicles']); $i<$n; $i++){
if ($named_array['vehicles'][$i]['vehicle'] == $val)
return $i;
}
return -1;
}
echo complex_index_of($named_array, 'i100-2 ');
// output: 1
Try something like this (maybe create a function, if you need to do it more than once)
$needle = 'i100-1';
$vIndex = -1;
foreach ($named_array["vehicles"] as $index => $data) {
if($data['vehicle'] == $needle) {
$vIndex = $index;
break;
}
}

How to skip the 1st key in an array loop?

I have the following code:
if ($_POST['submit'] == "Next") {
foreach($_POST['info'] as $key => $value) {
echo $value;
}
}
How do I get the foreach function to start from the 2nd key in the array?
For reasonably small arrays, use array_slice to create a second one:
foreach(array_slice($_POST['info'],1) as $key=>$value)
{
echo $value;
}
foreach(array_slice($_POST['info'], 1) as $key=>$value) {
echo $value;
}
Alternatively if you don't want to copy the array you could just do:
$isFirst = true;
foreach($_POST['info'] as $key=>$value) {
if ($isFirst) {
$isFirst = false;
continue;
}
echo $value;
}
Couldn't you just unset the array...
So if I had an array where I didn't want the first instance,
I could just:
unset($array[0]);
and that would remove the instance from the array.
If you were working with a normal array, I'd say to use something like
foreach (array_slice($ome_array, 1) as $k => $v {...
but, since you're looking at a user request, you don't have any real guarantees on the order in which the arguments might be returned - some browser/proxy might change its behavior or you might simply decide to modify your form in the future. Either way, it's in your best interest to ignore the ordering of the array and treat POST values as an unordered hash map, leaving you with two options :
copy the array and unset the key you want to ignore
loop through the whole array and continue when seeing the key you wish to ignore
in loop:
if ($key == 0) //or whatever
continue;
Alternative way is to use array pointers:
reset($_POST['info']); //set pointer to zero
while ($value=next($_POST['info']) //ponter+1, return value
{
echo key($_POST['info']).":".$value."\n";
}
If you're willing to throw the first element away, you can use array_shift(). However, this is slow on a huge array. A faster operation would be
reset($a);
unset(key($a));
On a array filled with 1000 elements the difference is quite minimal.
Test:
<?php
function slice($a)
{
foreach(array_slice($a, 1) as $key)
{
}
return true;
}
function skip($a)
{
$first = false;
foreach($a as $key)
{
if($first)
{
$first = false;
continue;
}
}
return true;
}
$array = array_fill(0, 1000, 'test');
$t1 = time() + microtime(true);
for ($i = 0; $i < 1000; $i++)
{
slice($array);
}
var_dump((time() + microtime(true)) - $t1);
echo '<hr />';
$t2 = time() + microtime(true);
for ($i = 0; $i < 1000; $i++)
{
skip($array);
}
var_dump((time() + microtime(true)) - $t2);
?>
Output:
float(0.23605012893677)
float(0.24102783203125)
Working Code From My Website For Skipping The First Result and Then Continue.
<?php
$counter = 0;
foreach ($categoriest as $category) { if ($counter++ == 0) continue; ?>
It is working on opencart also in tpl file do like this in case you need.
foreach($_POST['info'] as $key=>$value) {
if ($key == 0) { //or what ever the first key you're using is
continue;
} else {
echo $value;
}
}
if you structure your form differently
<input type='text' name='quiz[first]' value=""/>
<input type='text' name='quiz[second]' value=""/>
...then in your PHP
if( isset($_POST['quiz']) AND
is_array($_POST['quiz'])) {
//...and we'll skip $_POST['quiz']['first']
foreach($_POST['quiz'] as $key => $val){
if($key == "first") continue;
print $val;
}
}
...you can now just loop over that particular structure and access rest normally
How about something like this? Read off the first key and value using key() and current(), then array_shift() to dequeue the front element from the array (EDIT: Don't use array_shift(), it renumbers any numerical indices in the array, which you don't always want!).
<?php
$arr = array(
'one' => "ONE!!",
'two' => "TWO!!",
'three' => "TREE",
4 => "Fourth element",
99 => "We skipped a few here.."
) ;
$firstKey = key( $arr ) ;
$firstVal = current( $arr ) ;
echo( "OK, first values are $firstKey, $firstVal" ) ;
####array_shift( $arr ) ; #'dequeue' front element # BAD! renumbers!
unset( $arr[ $firstKey ] ) ; # BETTER!
echo( "Now for the rest of them" ) ;
foreach( $arr as $key=>$val )
{
echo( "$key => $val" ) ;
}
?>

Find the last element of an array while using a foreach loop in PHP

I am writing a SQL query creator using some parameters. In Java, it's very easy to detect the last element of an array from inside the for loop by just checking the current array position with the array length.
for(int i=0; i< arr.length;i++){
boolean isLastElem = i== (arr.length -1) ? true : false;
}
In PHP they have non-integer indexes to access arrays. So you must iterate over an array using a foreach loop. This becomes problematic when you need to take some decision (in my case to append or/and parameter while building query).
I am sure there must be some standard way of doing this.
How do you solve this in PHP?
It sounds like you want something like this:
$numItems = count($arr);
$i = 0;
foreach($arr as $key=>$value) {
if(++$i === $numItems) {
echo "last index!";
}
}
That being said, you don't -have- to iterate over an "array" using foreach in php.
You could get the value of the last key of the array using end(array_keys($array)) and compare it to the current key:
$last_key = end(array_keys($array));
foreach ($array as $key => $value) {
if ($key == $last_key) {
// last element
} else {
// not last element
}
}
Note: This doesn't work because calling next() advances the array pointer, so you're skipping every other element in the loop
why so complicated?
foreach($input as $key => $value) {
$ret .= "$value";
if (next($input)==true) $ret .= ",";
}
This will add a , behind every value except the last one!
When toEnd reaches 0 it means it is at the last iteration of the loop.
$toEnd = count($arr);
foreach($arr as $key=>$value) {
if (0 === --$toEnd) {
echo "last index! $value";
}
}
The last value is still available after the loop, so if you just want to use it for more stuff after the loop this is better:
foreach($arr as $key=>$value) {
//something
}
echo "last index! $key => $value";
If you do not want to treat the last value as special inside loops. This should be faster if you have large arrays. (If you reuse the array after the loop inside the same scope you have to "copy" the array first).
//If you use this in a large global code without namespaces or functions then you can copy the array like this:
//$array = $originalArrayName; //uncomment to copy an array you may use after this loop
//end($array); $lastKey = key($array); //uncomment if you use the keys
$lastValue = array_pop($array);
//do something special with the last value here before you process all the others?
echo "Last is $lastValue", "\n";
foreach ($array as $key => $value) {
//do something with all values before the last value
echo "All except last value: $value", "\n";
}
//do something special with the last value here after you process all the others?
echo "Last is $lastValue", "\n";
And to answer your original question "in my case to append or/and parameter while building query"; this will loop over all the values, then join them together to a string with " and " between them but not before the first value or after the last value:
$params = [];
foreach ($array as $value) {
$params[] = doSomething($value);
}
$parameters = implode(" and ", $params);
There are already many answers, but it's worth to look into iterators as well, especially as it has been asked for a standard way:
$arr = range(1, 3);
$it = new CachingIterator(new ArrayIterator($arr));
foreach($it as $key => $value)
{
if (!$it->hasNext()) echo 'Last:';
echo $value, "\n";
}
You might find something that does work more flexible for other cases, too.
One way could be to detect if the iterator has next. If there is no next attached to the iterator it means you are in the last loop.
foreach ($some_array as $element) {
if(!next($some_array)) {
// This is the last $element
}
}
SINCE PHP 7.3 :
You could get the value of the last key of the array using array_key_last($array) and compare it to the current key:
$last_key = array_key_last($array);
foreach ($array as $key => $value) {
if ($key == $last_key) {
// last element
} else {
// not last element
}
}
to get first and last element from foreach array
foreach($array as $value) {
if ($value === reset($array)) {
echo 'FIRST ELEMENT!';
}
if ($value === end($array)) {
echo 'LAST ITEM!';
}
}
So, if your array has unique array values, then determining last iteration is trivial:
foreach($array as $element) {
if ($element === end($array))
echo 'LAST ELEMENT!';
}
As you see, this works if last element is appearing just once in array, otherwise you get a false alarm. In it is not, you have to compare the keys (which are unique for sure).
foreach($array as $key => $element) {
end($array);
if ($key === key($array))
echo 'LAST ELEMENT!';
}
Also note the strict coparision operator, which is quite important in this case.
Don't add a comma after the last value:
The array:
$data = ['lorem', 'ipsum', 'dolor', 'sit', 'amet'];
The function:
$result = "";
foreach($data as $value) {
$resut .= (next($data)) ? "$value, " : $value;
}
The result:
print $result;
lorem, ipsum, dolor, sit, amet
You can still use that method with associative arrays:
$keys = array_keys($array);
for ($i = 0, $l = count($array); $i < $l; ++$i) {
$key = $array[$i];
$value = $array[$key];
$isLastItem = ($i == ($l - 1));
// do stuff
}
// or this way...
$i = 0;
$l = count($array);
foreach ($array as $key => $value) {
$isLastItem = ($i == ($l - 1));
// do stuff
++$i;
}
Assuming you have the array stored in a variable...
foreach($array as $key=>$value)
{
echo $value;
if($key != count($array)-1) { echo ", "; }
}
If you need to do something for every element except either the first or the last and only if there is more than one element in the array, I prefer the following solution.
I know there are many solutions above and posted months/one year before mine, but this is something I feel is fairly elegant in its own right. The check every loop is also a boolean check as opposed to a numeric "i=(count-1)" check, which may allow for less overhead.
The structure of the loop may feel awkward, but you can compare it to the ordering of thead (beginning), tfoot (end), tbody (current) in HTML table tags.
$first = true;
foreach($array as $key => $value) {
if ($first) {
$first = false;
// Do what you want to do before the first element
echo "List of key, value pairs:\n";
} else {
// Do what you want to do at the end of every element
// except the last, assuming the list has more than one element
echo "\n";
}
// Do what you want to do for the current element
echo $key . ' => ' . $value;
}
For instance, in web development terms, if you want to add a border-bottom to every element except the last in an unordered list (ul), then you can instead add a border-top to every element except the first (the CSS :first-child, supported by IE7+ and Firefox/Webkit supports this logic, whereas :last-child is not supported by IE7).
You can feel free to reuse the $first variable for each and every nested loop as well and things will work just fine since every loop makes $first false during the first process of the first iteration (so breaks/exceptions won't cause issues).
$first = true;
foreach($array as $key => $subArray) {
if ($first) {
$string = "List of key => value array pairs:\n";
$first = false;
} else {
echo "\n";
}
$string .= $key . '=>(';
$first = true;
foreach($subArray as $key => $value) {
if ($first) {
$first = false;
} else {
$string .= ', ';
}
$string .= $key . '=>' . $value;
}
$string .= ')';
}
echo $string;
Example output:
List of key => value array pairs:
key1=>(v1_key1=>v1_val1, v1_key2=>v1_val2)
key2=>(v2_key1=>v2_val1, v2_key2=>v2_val2, v2_key3=>v2_val3)
key3=>(v3_key1=>v3_val1)
This should be the easy way to find the last element:
foreach ( $array as $key => $a ) {
if ( end( array_keys( $array ) ) == $key ) {
echo "Last element";
} else {
echo "Just another element";
}
}
Reference : Link
I have a strong feeling that at the root of this "XY problem" the OP wanted just implode() function.
As your intention of finding the EOF array is just for the glue. Get introduced to the below tactic. You need not require the EOF:
$given_array = array('column1'=>'value1',
'column2'=>'value2',
'column3'=>'value3');
$glue = '';
foreach($given_array as $column_name=>$value){
$where .= " $glue $column_name = $value"; //appending the glue
$glue = 'AND';
}
echo $where;
o/p:
column1 = value1 AND column2 = value2 AND column3 = value3
How about using "end"?
http://php.net/manual/en/function.end.php
It sounds like you want something like this:
$array = array(
'First',
'Second',
'Third',
'Last'
);
foreach($array as $key => $value)
{
if(end($array) === $value)
{
echo "last index!" . $value;
}
}
$array = array("dog", "rabbit", "horse", "rat", "cat");
foreach($array as $index => $animal) {
if ($index === array_key_first($array))
echo $animal; // output: dog
if ($index === array_key_last($array))
echo $animal; // output: cat
}
you can do a count().
for ($i=0;$i<count(arr);$i++){
$i == count(arr)-1 ? true : false;
}
or if you're looking for ONLY the last element, you can use end().
end(arr);
returns only the last element.
and, as it turns out, you CAN index php arrays by integers. It's perfectly happy with
arr[1];
You could also do something like this:
end( $elements );
$endKey = key($elements);
foreach ($elements as $key => $value)
{
if ($key == $endKey) // -- this is the last item
{
// do something
}
// more code
}
I kinda like the following as I feel it is fairly neat. Let's assume we're creating a string with separators between all the elements: e.g. a,b,c
$first = true;
foreach ( $items as $item ) {
$str = ($first)?$first=false:", ".$item;
}
Here's my solution:
Simply get the count of your array, minus 1 (since they start in 0).
$lastkey = count($array) - 1;
foreach($array as $k=>$a){
if($k==$lastkey){
/*do something*/
}
}
foreach ($array as $key => $value) {
$class = ( $key !== count( $array ) -1 ) ? " class='not-last'" : " class='last'";
echo "<div{$class}>";
echo "$value['the_title']";
echo "</div>";
}
Reference
If it is a single dimensional array you can do this to keep it short and sweet:
foreach($items as $idx => $item) {
if (!isset($items[$idx+1])) {
print "I am last";
}
}
Here's another way you could do it:
$arr = range(1, 10);
$end = end($arr);
reset($arr);
while( list($k, $v) = each($arr) )
{
if( $n == $end )
{
echo 'last!';
}
else
{
echo sprintf('%s ', $v);
}
}
If I understand you, then all you need is to reverse the array and get the last element by a pop command:
$rev_array = array_reverse($array);
echo array_pop($rev_array);
You could also try this to make your query... shown here with INSERT
<?php
$week=array('one'=>'monday','two'=>'tuesday','three'=>'wednesday','four'=>'thursday','five'=>'friday','six'=>'saturday','seven'=>'sunday');
$keys = array_keys($week);
$string = "INSERT INTO my_table ('";
$string .= implode("','", $keys);
$string .= "') VALUES ('";
$string .= implode("','", $week);
$string .= "');";
echo $string;
?>
For SQL query generating scripts, or anything that does a different action for the first or last elements, it is much faster (almost twice as fast) to avoid using unneccessary variable checks.
The current accepted solution uses a loop and a check within the loop that will be made every_single_iteration, the correct (fast) way to do this is the following :
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
$some_item=$arr[$i];
$i++;
}
$last_item=$arr[$i];
$i++;
A little homemade benchmark showed the following:
test1: 100000 runs of model morg
time: 1869.3430423737 milliseconds
test2: 100000 runs of model if last
time: 3235.6359958649 milliseconds
Another way to go is to remember the previous loop cycle result and use that as the end result:
$result = $where = "";
foreach ($conditions as $col => $val) {
$result = $where .= $this->getAdapter()->quoteInto($col.' = ?', $val);
$where .= " AND ";
}
return $this->delete($result);

Categories