Pranav Jituri
Pranav Jituri

Reputation: 823

Getting Parse Error Unexpected "

I am getting an error with the following message :- Parse error: syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in C:\xampp\htdocs\game.php on line 12

Here is the source code :-

<?php
 $words=$_GET['words'];
  $array=explode(",",$words);
    $j=count($array)-1;
 goto a;

a:  shuffle($array);
    $num=$array[0];
    echo "The Number Is = $num";
    echo "<br />";
    echo "Please Enter The Number Within 10 Seconds";
    echo "<form method=\"get\" action=\"$_SERVER[\'PHP_SELF\']\" ";  **<--Line 12**
    echo "<input type=\"text\" name=\"num\"";
    echo "<input type=\"submit\" value=\"Press Me! \"";
    $input=$_GET['num'];
    goto b;

b: if($input==$array[0] && $array!=NULL)
    {
        array_pop($array);
        goto a;
        }
    elseif($array!=NULL)
        {
            goto a;
    }
else
    break;
?>

Please don't say about the GOTO but rather on how to fix the error as I am only experimenting with it to see if it would solve the given question.

Upvotes: 1

Views: 3094

Answers (7)

Fordi
Fordi

Reputation: 2876

I'll comment on all of it.

First, to fix your syntax error (and the later HTML errors you'll have). The single-quotes in the PHP_SELF substitution don't need escaped, you need to complete your opening tags, and you need to close your form tag.

<?php
 $words=$_GET['words'];
  $array=explode(",",$words);
    $j=count($array)-1;
 goto a;

a:  shuffle($array);
    $num=$array[0];
    echo "The Number Is = $num";
    echo "<br />";
    echo "Please Enter The Number Within 10 Seconds";
    echo "<form method=\"get\" action=\"$_SERVER['PHP_SELF']\" >";
    echo "<input type=\"text\" name=\"num\" />";
    echo "<input type=\"submit\" value=\"Press Me! \" />";
    echo "</form>";
    $input=$_GET['num'];
    goto b;

b: if($input==$array[0] && $array!=NULL)
    {
        array_pop($array);
        goto a;
        }
    elseif($array!=NULL)
        {
            goto a;
    }
else
    break;

Now, to make it not spaghetti code and to simplify your logic:

<?php
$words=$_GET['words'];
$array=explode(",",$words);

while (sizeOf($array) > 0) {
    shuffle($array);
    $num = $array[0];
    echo "The Number Is = $num";
    echo "<br />";
    echo "Please Enter The Number Within 10 Seconds";
    echo "<form method=\"get\" action=\"$_SERVER['PHP_SELF']\" >";
    echo "<input type=\"text\" name=\"num\" />";
    echo "<input type=\"submit\" value=\"Press Me! \" />";
    echo "</form>";
    $input = $_GET['num'];
    if($input === $array[0]) {
        array_pop($array);
    }
}

Now it's at least clear what the code does - that is, the form is provided with a comma-delimited list of numbers on the query parameter "words". The list is shuffled, and the user is asked to enter the new "first" item - effectively a random item from the list. When submitted by the user, "num" is passed. If this number is the same as the first in the list, it removes the last number. Either way, as long as the array is non-null, then loops back on itself (effectively ad infinitum, spitting out the same form for each number on the list. I'm not sure this is what you wanted, since you're not handling $_GET[num] as an array.

Assuming you actually get a form, rather than just peg your server, the script then checks if "num" is present and, if so, removes it from the numbers list.

This is where it gets interesting; on submission, the script is started again. "words" is empty, so the form asks the user to enter "". If it wasn't, the list would have been re-randomized, so even if the user dutifully entered what was asked, the script wouldn't recognize it.

This is one of the reasons we don't use GOTO; it obfuscates your code flow. What's clear in a while loop is inscrutable using GOTO.


So what I assume is supposed to be the requirement:

You're presented with a number to enter. You enter it and submit the form. The number is removed from the list, and you're asked to enter another one. Once it's empty, it would be nice if you're told that.

So, to do this in a way that makes sense, let's do this using some OOP.

I know what you're going to say: this appears to be more complex - however, I want you to note that what baking everything into a class does: it encapsulates the stuff you're doing into one place, and separates out each phase of the request into separate functions.

Additionally, comments notwithstanding, it effectively documents nonobvious and repetitive tasks, like getting items off the $_REQUEST (or $_GET) object, or getting an item from an array (if it's an array and if the item exists on it) in a way that is safe and predictable.

Lastly, it's readable. It's a bit of work to look at the contents of the while loop and work out what it does; in this class, you can tell: it checks that the array is not empty and that the submitted number is the same as the requested number; if so, it removes that number.

Additionally, rather than shuffle the list each time, we just pick each one off at random.

<?php
class RandomNumberGame {
    private $startCount;
    private $numberMax;
    private $numbers;
    private $index;
    /**
        Produce an array containing $count random numbers between 0 and $max
    */
    public function generateRandoms($count, $max) {
        $nums = array();
        for ($i = 0; $i < $count; $i += 1) {
            $nums[] = rand(0, $max);
        }
        return $nums;
    }
    /**
        Get an item from an array if it exists; if not, or if the array doesn't exist, return null
    */
    public function getIfExists($array, $item) {
        if (empty($array)) return null;
        if (!array_key_exists($item, $array)) return null;
        return $array[$item];
    }
    /**
        returns a random number from the list of numbers
    */
    function pickRandomNumber() {
        return rand(0, sizeof($this->numbers) - 1);
    }
    /**
        Handle the request data
            $request
                ['nums'] - list of numbers with which to populate $this->numbers
                ['index'] - the index of the currently-selected number
                ['num'] - the user's entry
        If nums[index] == num, that item is removed and a new index is selected.
    */
    public function processRequest($request) {
        $nums = $this->getIfExists($request, 'nums');
        if (empty($nums)) {
            $this->numbers = $this->generateRandoms($this->startCount, $this->numberMax);
        } else {
            $this->numbers = explode(',', $nums);
        }

        $this->index = $this->getIfExists($request, 'index');
        if (empty($this->index)) {
            $this->index = $this->pickRandomNumber();
        }

        $num = $this->getIfExists($request, 'num');
        if (empty($num)) return;
        while (!empty($this->numbers) && $this->getCurrentNumber() === $num) {
            $this->removeCurrentNumber();
        }
    }
    /**
        Removes the entry in $this->numbers pointed to by $this->index, and assigns $this->index a new random position
    */
    public function removeCurrentNumber() {
        // In $nums, replace 1 items at $index with [] - effectively, remove item $index from $num
        array_splice($this->numbers, $this->index, 1, array());
        // Pick a new random item
        $this->index = $this->pickRandomNumber();
    }
    /**
        Get the currently selected number
    */
    public function getCurrentNumber() {
        return $this->getIfExists($this->numbers, $this->index);
    }
    /**
        Generate the form for output to the user
        If there are no numbers left, provide a congratulation, and a link to start over
    */
    public function getForm($endpoint) {
        if (sizeof($this->numbers) === 0) {
            return "Hey, you're done! <a href=\"{$endpoint}\">Start over</a>.";
        }
        $nums = join(',', $this->numbers);
        return <<<HEREDOC
            <form method="post" action="{$endpoint}">
                <input type="hidden" name="nums" value="{$nums}" />
                <input type="hidden" name="index" value="{$this->index}" />
                <label for="num">
                    The number is {$this->getCurrentNumber()}<br />
                    Please enter the number within 10 seconds<br />
                    <input id="num" type="text" name="num" autofocus/>
                </label>
                <input type="submit" value="Press Me!" />
            </form>
            <!-- Optional: define some Javascript to disable the form in 10 seconds -->
HEREDOC;
    }
    public function RandomNumberGame($startCount = 10, $numberMax = 100) {
        //Basic initialization
        $this->startCount = $startCount;
        $this->numberMax = $numberMax;
    }
}
//Finally, the program:
$rng = new RandomNumberGame();
$rng->processRequest($_REQUEST);
echo $rng->getForm($_SERVER['PHP_SELF']);

Upvotes: 4

Funk Forty Niner
Funk Forty Niner

Reputation: 74217

You're missing closing > in three lines

echo "Please Enter The Number Within 10 Seconds";
echo "<form method=\"get\" action=\"$_SERVER[PHP_SELF]\">"; 
echo "<input type=\"text\" name=\"num\">";
echo "<input type=\"submit\" value=\"Press Me! \">";

Yours:

echo "<form method=\"get\" action=\"$_SERVER['PHP_SELF']\" "; 
                                                          ^-- here
echo "<input type=\"text\" name=\"num\"";
                                       ^-- here
echo "<input type=\"submit\" value=\"Press Me! \"";
                                                 ^-- here

Plus, [\'PHP_SELF\'] You should not be escaping single quotes.

Use [PHP_SELF] or {$_SERVER['PHP_SELF']} wrapping the variable in curly braces.

Upvotes: 1

Patrick
Patrick

Reputation: 3367

The answer is you're putting in single quotes for the array of $_SERVER:

echo "<form method=\"get\" action=\"$_SERVER[\'PHP_SELF\']\" ";

simply use

echo "<form method=\"get\" action=\"$_SERVER[PHP_SELF]\" ";

instead. the idea of the '' inside the array is to pass the string. no need to pass it within a quotes.

Upvotes: 1

Wige
Wige

Reputation: 3918

printf ("<form method=\"get\" action=\"{$_SERVER['PHP_SELF']}\" ");

Two errors. You can't escape single quotes in a double quoted string, and when you are working with an array inside a string, you need to surround it with {}.

Upvotes: 1

revo
revo

Reputation: 48711

You should wrap server variable with brackets:

echo "<form method=\"get\" action=\"{$_SERVER['PHP_SELF']}\">";  

Upvotes: 1

Gil
Gil

Reputation: 1804

Change

echo "<form method=\"get\" action=\"$_SERVER[\'PHP_SELF\']\" ";

Into

echo '<form method="get" action="'.$_SERVER['PHP_SELF'].'">';

It's much more simpler for the eyes.

Upvotes: 4

Matt The Ninja
Matt The Ninja

Reputation: 2731

Doesnt it need a space before the != and after From

b: if($input==$array[0] && $array!=NULL)

to this

b: if(($input==$array[0]) && ($array != NULL))

Have wrapped it in extra brackets for good measure too

Upvotes: 0

Related Questions