I'm using private fields for the name attributes in forms instead of hard coding the values. However, by some reason the values isn't fetched from the private fields and put into the name attributes, and I just can't figure out why.
<?php
namespace View;
class UserView {
private $checkBox = "check[]";
private $submitRemove = "submitRemove";
public function ShowUsers() {
$userNameArray = array("foo", "bar", "hallo", "world");
$userIdArray = array(1, 2, 3);
$users = "";
$nrOfUsers = count($userNameArray);
// Name attribute of input fields created is left blank
for ($i = 0; $i < $nrOfUsers; $i++) {
$users .= "<label for='$userIdArray[$i]'>
$userNameArray[$i]
<input type='checkbox' name='$this->checkBox' value='$userIdArray[$i]' /><br/>
</label>";
}
$userList = "<div class='userList'>
<form id='form3' method='post' action=''>
<fieldset>
<p>Existing users</p>
$users
<input type='submit' id='$this->submitRemove' name='$this->submitRemove' Value='Ta bort' /> // name attribute is left blank
</fieldset>
</form>
</div>";
return $userList;
}
For "complex elements", such as arrays or attributes of an object, you can't call them just like a variable in a double-quoted string.
You have to escape them with braces:
<?php echo "This is a complex attribute: {$this->checkBox}"; ?>
or you can remove them from the quoted string:
<?php echo "This is a complex attribute: " . $this->checkBox; ?>
BTW, double quoted strings aren't recommended due to performance issues. Using simple quoted strings is better, it avoid to PHP to "read" the string to verify if there's a variable to display.
BTW2, to make your code more readable, a convention in PHP says that private attributes have to start by an underscore. You should rename $checkBox and $submitRemove to $_checkBox and $_submitrRemove.
BTW3, if those 2 variables aren't intented to change, you should consider to declare them as static variables. It'll prevent to have multiple copies of those variables inside each of instatiated objects.
There is nothing wrong with the posted code. I think you are overwriting $submitRemove somewhere in another method.
Related
I'm trying to use foreach to print the results of a SQL query from an associative array. I'm trying different things and one works while the other gives an error.
I'm specifically asking about why this portion $row[first_name] gives different results.
This code works:
<?php
include 'connect_db.php';
$stmt = $conn->query("SELECT people.first_name, people.last_name FROM people");
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $row) {
echo "<form action='/test.php' method='post'>
<input type='text' name='first_name' value=$row[first_name]>
<input type='submit' value='Click'> <br>
</form>";
}
?>
But the following code gives an error saying: Notice: Use of undefined constant first_name - assumed 'first_name'
<?php
include 'connect_db.php';
$stmt = $conn->query("SELECT people.first_name, people.last_name FROM people");
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $row) {
echo $row[first_name];
}
?>
I'm obviously using $row[first_name] incorrectly in the 2nd example but I can't figure out how.
When using an undefined constant, PHP will automatically assume a string was intended. [sic]
PHP assumes that you mean the name of the constant itself, just as if
you called it as a string
Example: https://3v4l.org/C7PgT
As noted in the PHP 7.x, it will result in an ERROR as opposed to a warning in future versions, so its use should be avoided in favor of using quoted strings
Why $foo[bar] is wrong: [sic]
Always use quotes around a string literal array index. For example,
$foo['bar'] is correct, while $foo[bar] is not.
The reason is that this code has an undefined constant (bar) rather than a string ('bar' - notice the quotes).
if there is no defined constant named bar, then PHP will substitute in the string 'bar' and use that.
This does not mean to always quote the key. Do not quote keys which are constants or variables, as this will prevent PHP from interpreting them.
When you used it within a double-quoted context ("$var"), PHP's lexer automatically used the text within the brackets ($var[text]) as a string.
Also PHP's lexer has issues when using array or objects within double quotes.
echo "value=$row['first_name']"; //results in a syntax error
Example: https://3v4l.org/K6fUd
To resolve this issue you would need to wrap your array with curly-brackets
echo "value={$row['first_name']}";
Excample: https://3v4l.org/aQ1sJ
Instead I highly suggest conforming to single quotes for all PHP output to save you from having to read between different syntax and HTML syntax uniformity.
foreach ($results as $row) {
echo '<form action="/test.php" method="post">
<input type="text" name="first_name" value="' . $row['first_name'] . '">
<input type="submit" value="Click"><br>
</form>';
}
Alternatively using HEREDOC or NOWDOC depending on desired output.
foreach ($rows as $row) {
echo <<<EOT
value="{$row['first_name']}"
EOT;
}
Example (including HEREDOC): https://3v4l.org/7K5ap
My preferred method is to ensure all HTML syntax is output directly or to the output buffer. As it allows for most IDE's, such as PHPStorm, to automatically distinguish it as HTML and not PHP code, to ensure HTML syntax is valid and matches with other tags.
<?php foreach ($results as $row) { ?>
<form action="/test.php" method="post">
<input type="text" name="first_name" value="<?php echo $row['first_name']; ?>">
<input type="submit" value="Click"><br>
</form>
<?php } ?>
The keys in an associative array returned from MySQL are strings - you need to quote them:
echo $row['first_name'];
# Here ---^----------^
I want to create a function which a static variable because I need to preserve the variable value between functions. The first way, this variable include the last index an array, and the value will be changed the second run. If I use count() to search the last array index, I get the following error: Parse error: parse error, expecting ','' or';'' in C:\wamp\www\rekurzio\index.php on line 11
<form method="POST">
Search the following number: <input type="number" name="numberQuestion">! <br>
<input type="submit" name="search" value="Search">
</form>
<?php function search(){
global $numberArray;
$numberQuestion = $_POST['numberQuestion'];
static $searchDirection = "RIGHT";
static $lowerLimit = 0; //it is the first array index
static $upperLimit = count($numberArray)-1 /* 8 */; //it is the last array index, but it doesn't work
if($lowerLimit == $numberQuestion){
$searchResult = "I found the $numberQuestion value which the $lowerLimit element";
echo $searchResult;
}else if($upperLimit == $numberQuestion){
$searchResult = "I found the $numberQuestion value which the $upperLimit element";
echo $searchResult;
}else{
$middleElement = ($lowerLimit+$upperLimit)/2;
if($middleElement == $numberQuestion){
$searchResult = "I found the $numberQuestion value which the $middleElement element";
echo $searchResult;
}else{
if($numberQuestion < $middleElement){
$searchDirection = "LEFT";
}else if($numberQuestion > $middleElement){
$searchDirection = "RIGHT";
}
if($searchDirection == "RIGHT"){
$lowerLimit = $middleElement;
}else if($searchDirection == "LEFT"){
$upperLimit = $middleElement;
}
search();
}
}
}
if(isset($_POST['search'])){
search();
} ?>
How can I search the last array index?
Static declarations are resolved in compile-time, therefore trying to assign values to these variables which are the result of expressions will cause a parse error. For reference, see the manual.
So static variables may only be initialized using a literal or constant; expressions are not allowed. While you may initialize a static variable to an integer or array (for instance), you may not initialize it to another variable, to a function return value, or to an object.
UPDATE:
In your case I would advise that the 3 static-scoped variables ($searchDirection, $lowerLimit and $upperLimit) be function parameters instead of static variables. In this case their scope is still local to the search function, however you may dynamically set the proper values before the initial and then the recursive calls of the function.
I could not comment because I do not have enough reputations.
I suggest you do two things:
First: convert line 11 into
static $upperLimit = count($numberArray)-1; /* 8 */
Second, do var_dump($numberArray); before the line above. It seems that there is some sort of simple syntax error over there.
When I print the $letter variable, I am not getting the correct value. It always coming 0.
index.php
<form method="get" class="txtweb-form" action="index.php">
Guess a letter: <input type="text" name="txtweb-message" />
<input type="submit" value="submit" name="guess" />
</form>
<?php
$params = (object) $_REQUEST;
//print_r($params);
if (isset($params->guess)) {
$letter = $params->txtweb-message;
echo $letter;exit;
}
?>
You need to probably use _ instead of - in input name. - is not a valid character in PHP variable of property names.
What is actually happening is this:
$letter = $params->txtweb - message; // a subtraction operation
You end up subtracting an unset constant message from an unset object property $params->txtweb. Thus you get 0.
You can keep - in input name but you should use $_REQUEST['txtweb-message'] or $_GET['txtweb-message'] (without casting to object) to retrieve the value.
There really is no reason whatsoever to cast the superglobal array to an object, and this is what introduced your issue.
An additional note here. You really should be developing with error reporting turned on. That operation shown above would have resulted in two warnings showing up, which could have helped you understand what is happening.
why are you casting into an object?
wouldn't treating it as an array be easier like
<?php
$params = $_REQUEST;
if (isset($params["guess"])) {
$letter = $params["txtweb-message"];
echo $letter;exit;
}
?>
I'm having trouble displaying an array value inside a heredoc input field. Here's a snippet of code:
class Snippet{
protected $_user;
protected $_class;
protected $_messages;
public function __construct(){
$this->_user = $this->_class = NULL;
$this->createUser();
}
public function createUser(){
$keys = array('user_login','user_email');
$this->_user = $this->_class = array_fill_keys($keys, '');
}
public function userErrors(){
//by default give the login field autofocus
$_class['user_login'] = 'autofocus';
}
public function getForm(){
return <<<HTML
<form id='test' action='' method='post'>
$this->_messages
<fieldset>
<legend>Testing Heredoc</legend>
<ol>
<li>
<label for='user_login'>Username</label>
<input id='user_login' name='user_login' type='text' placeholder='Login name' value=$this->_user[user_login] $this->_class[user_login]>
</li>
</ol>
</fieldset>
</form>
HTML;
}
}
My output yields a labeled input box with the value displayed as Array[user_login].
I can assign the array to separate variables and get the output I'm looking for, but this seems like an unnecessary waste. PHP 5.3.5
Wrap your array variable inside curly braces {} like this
value="{$this->_user['user_login']} {$this->_class['user_login']}"
Here is a nice article on this.
From the article
Unfortunately, PHP doesn’t provide any direct means for calling
functions or outputting expression results in HEREDOC strings. The
problem here is that, unless the thing in the curly braces starts with
a dollar sign, it can’t be recognized by PHP as something to be
replaced.
What is the meaning of { } (curly braces) in string literals in PHP?
This is the complex (curly) syntax for string interpolation. From the manual:
Complex (curly) syntax
This isn't called complex because the syntax is complex, but because
it allows for the use of complex expressions.
Any scalar variable, array element or object property with a string
representation can be included via this syntax. Simply write the
expression the same way as it would appear outside the string, and
then wrap it in { and }. Since { can not be escaped, this syntax
will only be recognised when the $ immediately follows the {. Use
{\$ to get a literal {$. Some examples to make it clear:
<?php
// Show all errors
error_reporting(E_ALL);
$great = 'fantastic';
// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
// Works
echo "This square is {$square->width}00 centimeters broad.";
// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";
// Works
echo "This works: {$arr[4][3]}";
// This is wrong for the same reason as $foo[bar] is wrong outside a string.
// In other words, it will still work, but only because PHP first looks for a
// constant named foo; an error of level E_NOTICE (undefined constant) will be
// thrown.
echo "This is wrong: {$arr[foo][3]}";
// Works. When using multi-dimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][3]}";
// Works.
echo "This works: " . $arr['foo'][3];
echo "This works too: {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
echo "This is the value of the var named by the return value of getName(): {${getName()}}";
echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
// Won't work, outputs: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>
Often, this syntax is unnecessary. For example, this:
$a = 'abcd';
$out = "$a $a"; // "abcd abcd";
behaves exactly the same as this:
$out = "{$a} {$a}"; // same
So the curly braces are unnecessary. But this:
$out = "$aefgh";
will, depending on your error level, either not work or produce an error because there's no variable named $aefgh, so you need to do:
$out = "${a}efgh"; // or
$out = "{$a}efgh";
As for me, curly braces serve as a substitution for concatenation, they are quicker to type and code looks cleaner. Remember to use double quotes (" ") as their content is parsed by PHP, because in single quotes (' ') you'll get the literal name of variable provided:
<?php
$a = '12345';
// This works:
echo "qwe{$a}rty"; // qwe12345rty, using braces
echo "qwe" . $a . "rty"; // qwe12345rty, concatenation used
// Does not work:
echo 'qwe{$a}rty'; // qwe{$a}rty, single quotes are not parsed
echo "qwe$arty"; // qwe, because $a became $arty, which is undefined
?>
Example:
$number = 4;
print "You have the {$number}th edition book";
//output: "You have the 4th edition book";
Without curly braces PHP would try to find a variable named $numberth, that doesn't exist!
I've also found it useful to access object attributes where the attribute names vary by some iterator. For example, I have used the pattern below for a set of time periods: hour, day, month.
$periods=array('hour', 'day', 'month');
foreach ($periods as $period)
{
$this->{'value_'.$period}=1;
}
This same pattern can also be used to access class methods. Just build up the method name in the same manner, using strings and string variables.
You could easily argue to just use an array for the value storage by period. If this application were PHP only, I would agree. I use this pattern when the class attributes map to fields in a database table. While it is possible to store arrays in a database using serialization, it is inefficient, and pointless if the individual fields must be indexed. I often add an array of the field names, keyed by the iterator, for the best of both worlds.
class timevalues
{
// Database table values:
public $value_hour; // maps to values.value_hour
public $value_day; // maps to values.value_day
public $value_month; // maps to values.value_month
public $values=array();
public function __construct()
{
$this->value_hour=0;
$this->value_day=0;
$this->value_month=0;
$this->values=array(
'hour'=>$this->value_hour,
'day'=>$this->value_day,
'month'=>$this->value_month,
);
}
}