Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I run into refactoring problem. I have many similar methods, but i cannot find way to extract one line form them and make another private method.
private function constructRules($rules, \Languages $langs) {
foreach ($rules as $fieldType => $rule) {
foreach ($langs->all() as $lang) {
//line below changes
$langRules[$fieldType . '[' . $lang->lang . ']'] = $rule;
}
}
return $langRules;
}
I have these foreach loops in 4 different places. If i extact foreach loops and return array, I still need to make one foreach loop in method, to fill $langRules in this example. Maybe there are simple way to do it, but I am not able to see it...
Is it not just a matter of factoring out the "task" part of that code into a callback?
private function constructRulesUsingCallBack($rules, \Languages $langs, $task) {
$langRules = [];
foreach ($rules as $fieldType => $rule) {
foreach ($langs->all() as $lang) {
$task($langRules, $fieldType, $lang, $rule);
}
}
return $langRules;
}
$langRules = constructRulesUsingCallBack($rules, $langs, function (&$langRules, $fieldType, $lang, $rule) {
$langRules[$fieldType . '[' . $lang->lang . ']'] = $rule;
});
I'm not so au fait with PHP, and I am not happy with the amount of boilerplate I need in the inline function expression to work, but PHP doesn't seem to implement closure very well (that I could work out, anyhow).
However you can leave the constructRulesUsingCallBack() function as is to just handle the looping now, and simply pass a different implementation of the callback body to it each time you need to process something within those loops.
That seems to fulfil what you need it to, based on your example. If not, pls clarify and I might be able to augment this to cover your needs.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am looking for smart solution, maybe you could help me out. Currently I am doing an own Authentication (Separate Class) system for my Webshop project. My problem is, that I need conditional statement inside foreach loop, to return the code (see below). Any suggestions?
My code currently look like this
public function regiAuth($email, $password, $firstname, $lastname)
{
$authContainer = [$email, $password, $firstname, $lastname];
foreach ($authContainer as $a) {
return !empty($_POST[$a]);
}
}
And I want to result this (With &&)
return !empty($_POST[$email]) && !empty($_POST[$password]) &&
!empty($_POST[$firstname]) && !empty($_POST[$lastname])
I believe you could do simply by do
foreach ($authContainer as $a) {
if (empty($_POST[$a])
return false;
}
return true;
instead of checking if all of them are full, you look if there is at least one empty.
it is a good practice to stop iteration if you find one element that is not as expected, imagine if you had an array of hundreads of assertions to do.
making an full if statement would look like this, here it checks if the $_POST are not empty. && means that both have to true or false
foreach ($authContainer as $a) {
if((!$_POST[$email]) && (!$_POST[$password])){
return false;
}
}
return true;
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
My php code is:
<?php
class Product {
var $product_name;
var $retailer;
function __constructor($product, $retailer) {
$this->product_name = $product;
$this->retailer = $retailer;
}
function getProduct() {
return $this->product_name;
}
}
$product_arr = array();
for ($f = 0; $f < 100; $f++) {
array_push($product_arr, new Product("asd", "xcxcxc"));
}
print_r($product_arr);
?>
The code is pretty simple, I have a class called "Product", I build an array consists of 100 Product object, but when I tried to print the array, I found out all the object's product_name and retailer fields are empty. Not sure why this happens.
Wrong name:
function __constructor($product, $retailer) {
^^^
PHP's standard constructor name is simply __construct (no or). So you never actually called a constructor, which means your variable assignments never executed.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Is it possible to do something like this:
if ($boolean == true) {
foreach ($variables as $variable) {
}
// some code that can be run either with a loop or without
if ($boolean == true) {
} // end the foreach loop
}
Or is there another way to do this without rewriting the same code twice just to satisfy all possibilities?
The conventional way is to always use a loop. If there is only one item, then you can still loop just once.
Contrived example
$values = …;
if (!is_array($values)) {
$values = array($values);
}
foreach ($values as $value) {
// Do your work
}
I'm not sure if I understand exactly what you're asking, but if you want to run a loop at least once, and continue looping for a condition then "Do While" is your answer. A do while works just like a while, but checks AFTER the first loop is run - meaning it always runs at least once.
PHP Docs for Do While
Do-while loops are very similar to while loops, except the truth expression is checked at the end of each iteration instead of in the beginning.
Example:
$arrayofstuff = array('one ','two ','three '); // Optional array of stuff
$i=0; // Counts the loops
echo 'starting...';
do {
// Do stuff at least once here
// Array stuff if needed
if(isset($arrayofstuff[$i])) {
echo $arrayofstuff[$i]; // Uses loop # to get from array
} else {
break; // ends loop because array is empty
}
$i++;
} while (true);
For what it's worth, forcing a variable into a single value array would probably be easier to read. As you can see there's a lot going on here for such a simple task.
(Dionne Warwick voice) That's what functions are for:
function doSomething() {
//whatever
};
if ($boolean)
for($variables as $variable) doSomething();
else
doSomething();
That kind of syntax you thought about isn't valid in PHP. It's a very clever idea though. But code maintenance of one of there would bring hell on earth. Better forget it.
why not just plain:
if($boolean){
foreach($a as $b){
// do stuff
}
}else{
// do other stuff
}
What you want would be done like so...
foreach ($variables as $variable) {
// some code that can be run either with a loop or without
if ($boolean !== true) {
break;
}
}
But this is not as readable as just using an if/else statement
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How do I check that a PHP array is not empty?
// If $columns array is not empty...
foreach ($columns as $column) {
echo $column;
}
Why bother with functions? Empty arrays will simply return false:
if ($array) {
// array is not empty
}
Very simple: using empty() function.
if (!empty($columns)){
foreach ($columns as $column) {
echo $column;
}
}
Also can be used with other types than array.
One way is to use count()
if (count($columns) > 0) {
foreach ($columns as $column) {
echo $column;
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Suppose that whe have some object, derived from these class instances
class A
{
...
private b //list of object of class B
}
class B
{
...
private c //list of object of class C
}
class C
{
...
private id
}
Now, somewhere in my code, I've got this situation
function findId(array $idList)
{
[...]
}
Where I have to find (for each element of $idList) if an element is contained into this object "cascade"
First solution
//object initialization
foreach($a->getB() as $b)
{
foreach($b->getC() as $c)
{
foreach($idList as $id)
{
if($id == $c->getId())
{
//do something an break the cycle
}
}
}
}
Second Solution
//object initialization
$idSet = array();
foreach($a->getB() as $b)
{
foreach($b->getC() as $c)
{
$idSet[] = $c->getId();
}
}
$idSet = array_unique($idSet);
foreach($idList as $id)
{
if(array_search($id,$idSet) !== false)
{
[...]
}
}
Which is better? There are some alternative methods for reach my goal?
IMPORTANT
There isn't better data representation. This because these objects are some database object (doctrine2)
You can actually combine the two approaches...
foreach($a->getB() as $b)
{
foreach($b->getC() as $c)
{
if (in_array($id, $idList)) {
...
And if you absolutely can't optimize in a way you won't have inner loop, set the values of $idList as keys, and values as true, and use isset() instead of in_array(), since it's the fastest
I would say that both are bad, they will in worst case give O(n^3), cause of the three for each loops. Is there maybe a better represenation of the data, in order to avoid all these loops?
If the answer is no, i would go with the first approach in order to avoid creating a new set.