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;
}
?>
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'm relatively new to OO PHP, and frankly PHP in general. I have a class that I assign the array values in the constructor. However, when I access the array later, it is telling me that the array is null. Any ideas how this is going out of scope?
class SentenceContentContainer {
public $strSentence; //theSentence entered
public $arrayOfWords = []; //words in the sentence
private $num_words_in_sentence;
function __construct($strSentence)
{
$this->strSentence = $strSentence;
$arrayOfWords = explode(" ", $strSentence); //get the array of words in the string
$num_words_in_sentence = count($arrayOfWords); //count elements in the sentence
}
function sortHighestLetterRepeaterOfSentence()
{
usort($arrayOfWords, "compare"); //says parameter 1 is null
}
...
}
This is accessed from:
<html>
<head><title>PHP Code</title></head>
<body>
<?php
include "classes.php";
//process the data input
$post_string = implode("",$_POST); //change post array to string
// instantiate 1 of 2 objects
$sentenceCC = new SentenceContentContainer($post_string);
call_user_method("sortHighestLetterRepeaterOfSentence",$sentenceCC);
?>
<form method="post" action="">
<input type="text" name="value">
<input type="submit">
</form>
</body>
</html>
When I tried adding this->arrayOfWords in the Sentence contructor, it said it was a syntax issue.
I wonder if the issue is that somehow it's running the call_user_method even though I haven't hit submit yet in the form, after entering the sentence? I wouldn't think it would have gotten there yet?
Added: When I invoke the script in the browser, before I hit submit in the form, is when I see the warning message.
Added Also: Maybe I need to check that $arrayOfWords is not null or something in sortHighestLetterRepeaterOfSentence? I tried adding a check for null, but It's saying Undefined variable arrayOfWords where I test it for != null. I was also considering isset, but it's unclear that this would fix it.
$arrayOfWords is a variable that only exists inside the __construct function.
$this->arrayOfWords is a private class variable that exists in any method of the class and has a different value per-instance.
P.S. Why are you using call_user_method? This function is deprecated (and I think removed in PHP 7). Just a quick note, if you saw that in a tutorial, you should consider a new tutorial as that one's gonna be outdated.
You can just do:
$sentenceCC->sortHighestLetterRepeaterOfSentence()
If you must, you can use call_user_func instead:
call_user_func([$sentenceCC, 'sortHighestLetterRepeaterOfSentence']);
Yes this code will execute even if form is not submitted.
I think your should check $_POST variable and allow to run your code only
if (count( $_POST ))
Is it possible to get empty array(array with 0 items) value via $_GET?
Is it possible with direct value setting?
count($_GET['param'])==0
You just need an empty value url = myform.php?param=¶m2=
In form just let the value blank:
<input type='text' name='param' value ='' />
For an empty array:
url: myform.php?param[]=¶m2[some_key]=
in form: <input type='text' name='param[]' value ='' />
From Ajax: (I remember this was so anti-intuitive and hard to search for):
ajax{
...
data: {'params[]':'','params2[some_key]':''}
}
Workaround:
Just edit the back-end and if there is no data for params or it is not an array (null, empty whatever ..) just assign an empty string to it:
$param = (isset($_GET['param']) && is_array($_GET['param']))? $_GET['param'] : array();
Update:
I did few tests and it seems there is no way to put "nothing" in the request ussing a form or ajax.
0, '', Null are valid values for the $_GET but empty array is not even created.
So to answer your question, it is NOT possible to get empty array value from the front-end.
There are few options to edit $_GET manually in the back-end:
<?php
if(!isset($_GET['param']) || !$_GET['param']){ //not set or (null,0,"")
$_GET['param'] = array();
}
if(count($_GET['param'])==0){...}; // 0 if no 'param' was provided.
If array is empty or containing values that doesn't matters. Just declare a variable and pass the $_GET[] to the variable.
for example,
$para=$_GET['param'];
and now
if(is_array($para))
{
//
}
else{
$para=new array();
}
passing empty array via GET is not possible under normal situation. That said, I can think of a really rare way that the checking you used will return true.
http://domain.com/receiver?param=a%3A0%3A%7B%7D
The above is basically a serialized and urlencoded empty array with the key 'param'
if the target server have some sort of filter that auto unserialize all incoming data, then it might happen.
(or something like the below)
foreach($_GET as $key => $value){
$_GET[$key] = unserialize($value);
}
count($_GET['param'])==0
I know this is a far fetch but it is possible, maybe some private test server that only handles serialized data but accidentally open to public e.t.c.
That said, it is still only passing a serialized empty array instead of a empty array itself. But let's be honest, this answer is more like a joke/fun answer that tries to point out under some very rare case
count($_GET['param'])==0
will return true (Without actively assigning values # server side)
I was trying to create a site like random.org in PHP but when i go to the page i receive an error at the line 36 (the $random = rand($first,$last); How can i solve it?
here is the code!
<form action="numero.php" method="post">
<input type="text" name="first">
<input type="submit" value="last">
</form>
<?php
function random() {
$first = $_POST['first'];
$last = $_POST['last']
$random = rand($first,$last);
}
echo random();
?>
You are missing a semicolon:
$last = $_POST['last']; // <- here you missed it.
$random = rand($first,$last);
Therefore you are seeing an error. To prevent this, you can check the syntax with
php -l your_file.php
There are more problems with your code, like checking if it is a GET request (and need to show the form) or a POST request (and thus need to process your form data).
The first time you load this page you won't have any POST data. So you need to wrap your stuff in an if and test if those variables are set.
function random() {
if(isset($_POST['first'])){
$first = $_POST['first'];
$last = $_POST['last'];
} else {
$first = 1;
$last = 10;
}
$random = rand($first,$last);
}
PHP's built in rand(); function will only take in numbers as an argument.
Since you are passing the value last in your submit button, the function will throw an error.
If you give it a numeric value, this should be solved. Or better, retrieve the data from a hidden field so that you can keep the value inside your button the same.
EDIT
As noted above, you are also missing a semicolon (;) after your $_POST['last'].
rand($min,$max) takes integers. By default, the values of $_POST are strings. Convert them first:
rand(intval($first),intval($last));
Looking at php.net for the function it takes int values. I would suggest you check the post values for the desired types.
Also check the max value as mentioned on php.net also.
Where do you define the post name last?
I don't see it in the form.
Ladies and gents,
I found a very strange behavior which I cannot explain:
Assume that you have
multiple form elements on your page, maybe rendered by php
each form has one input field with an unique name
on the beginning of that page a session will be started
you store every posted input value in the $_SESSION variable
like this:
<?php
session_start();
$_SESSION["Test"] = "Hello";
foreach ($_POST as $name => $value) {
//echo "_POST: " . $name . ":" . $value . "<br>";
$_SESSION[$name] = $value;
//session_commit();
}
for ($i = 0; $i < 10; $i++) {
echo "<form action=\"multiform.php\" method=\"post\">Value for input $i: <input type=\"text\" name=\"input".$i."\"></form>\n";
}
print_r($_SESSION);
?>
If you use the above code, only the "Test" = "Hallo" will persist after the refresh of the page. Regardless which input value has been posted and stored into the session by the foreach, it will be gone after refresh.
Now the interesting part:
If you add a name to the form like this...
echo "<form name=\"form$i\" action=\"multiform.php\" method=\"post\">Value for input $i: <input type=\"text\" name=\"input".$i."\"></form>\n";
...the posted values will be stored then.
But why?
What has the form name to do with the persistence of the $_SESSION?
EDIT: If the input name only contains numbers, the problem seems to arraise:
<input type=\"text\" name=\"$i\">
Thanks for clarifyng this.
Jan
EDIT2:
If the accessor key for the $_SESSION array only contains numbers, php obviously does not persist the values, so something like this, won't be stored:
<?php
session_start();
for ($i = 1; $i < 10; $i++)
{
$_SESSION[$i] = "Hello $i";
}
?>
The confusing part is, if you do a
print_r($_SESSION)
just after the for loop, it will show 1-10 with Hello 1..10...
Though, after refresh it's gone...
The keys in the $_SESSION associative array are subject to the same limitations as regular variable names in PHP, i.e. they cannot start with a number and must start with a letter or underscore.
Found at http://php.net/manual/en/session.examples.basic.php
Could the problem be the integer as a form name as your edit comment suggests? If you serialize a form using PHP you end up with a variable which name is an integer and PHP's variable name cannot be a plain number. If your problem doesn't persist with a naming convention such as <input type=\"text\" name=\"sometext_$i\">, you should stop using plain numbers as a form element name.
It's also a good idea to give the form fields descriptive names. Form field named "1" or "2" doesn't really tell you anything about the containing value.
This is correct; you can not use a numeric-only key in $_SESSION. Trying to do so with error_reporting on highest level and display_errors set to true will yield a notice:
PHP Notice: Unknown: Skipping numeric key 0 in Unknown on line 0
It does store it in the $_SESSION array, but not actually in the session. Although strange behaviour, the notice is descriptive enough. The fix is easy, by the way, just create an array in $_SESSION['numbers'], for example.
<?php
session_start();
for ($i = 1; $i < 10; $i++) {
$_SESSION['numbers'][$i] = "Hello $i";
}
var_dump( $_SESSION['numbers'] );