Parse error: syntax error, unexpected 'Ip' (T_STRING) in

Ip is a column in a database for IP addresses, I'm storing as Varchar with 15 as a value

Mainly because I don't want to mess with converting to accommodate ipv4 / ipv6, mainly because I don't know how to / don't want to if it is not necessary.

I'm only using the IP's to match the user in an account creation process that is multiple-step.

IP address is recorded fine into the database, I'm not sure if I'm actually getting it back out as shown by this error

These are the lines of code involved

$conn = new mysqli($servername, $username, $password, $dbname);

$row_cnt = $conn->num_rows;

$i = SELECT Ip FROM NewAccount WHERE Id=$row_cnt;

$ipt = $_SERVER['REMOTE_ADDR'];

if ($ipt == $i) {

Thank you for any help

    greenace92 wrote:

    Parse error: syntax error, unexpected 'Ip' (T_STRING) in

    The error that you received is due to you failing to place the SQL statement in a PHP string, i.e.,

    $i = SELECT Ip FROM NewAccount WHERE Id=$row_cnt;

    should have been:

    $i = "SELECT Ip FROM NewAccount WHERE Id=$row_cnt";

    But this is just a small part of the problem: you cannot just access $conn->num_rows like that as it does not even exist. Furthermore, you're missing a rather important part of the process of selecting from the database, i.e., you forgot to actually execute the SQL statement.

    greenace92 wrote:

    I'm only using the IP's to match the user in an account creation process that is multiple-step.

    This is problematic as a previous user could have had the same IP address. What exactly do you mean by "multiple-step"? For example, does this mean that the user first registers, then has to complete profile details in a form wizard spanning multiple pages? If so, then one option would be to log the user in after registration, and then based on how you identify the logged in user (e.g., by storing the user id in a session), you can then construct and execute the SQL statement.

      This is not complete code

      I would like to think that the likely-hood of two people creating an account from the same shared network ip addres is low to none but I am counting on the auto-increment function... the person is matched by the ID number assigned to him/her and then their IP address that they used to initially start the account creation process.

      It is a two part process because I wanted them to simply enter their name, age and gender then "create account"

      I suppose I could just do it all at once but part of the process is showing their information on a display and they can see their name on something and have the ability to decide if they like it or not

      So this is the first page where they enter name/age/gender

      <?php
      
      global $name, $age, $gender ;
      
      $name = $_POST['name'];
        $age = $_POST['age'];
        $gender = $_POST['gender'];
      
        $name = mysql_real_escape_string($name);
        $age = mysql_real_escape_int($age);
        $gender = mysql_real_escape_string($gender);
      
      ?>

      Then a .php file handles the posted data

      <?php
      
      header("Location: ");
      
      error_reporting(E_ALL);
      error_reporting(-1);
      
      $servername = "localhost";
      $username = "";
      $password = "";
      $dbname = "";
      
      // Create connection
      $conn = new mysqli($servername, $username, $password, $dbname);
      // Check connection
      if ($conn->connect_error) {
          die("Connection failed: " . $conn->connect_error);
      } 
      
      $i = $_SERVER['REMOTE_ADDR'];
      
      $row_cnt = $conn->num_rows;
      
      $c = $row_cnt;
      
      $sql = "INSERT INTO NewAccount (Id,Ip,Name,Age,Gender)
      VALUES ('$c++','$i', '{$_POST['name']}','{$_POST['age']}','{$_POST['gender']}')";
      
      mysql_query($sql);
      
      if ($conn->query($sql) === TRUE) {
          echo "New record created successfully";
      } else {
          echo "Error: " . $sql . "<br>" . $conn->error;
      }
      
      print_r($_POST);
      
      $conn->close();
      
      exit;
      ?>

      Then I try to pull the data to fill out fields / decide graphical output based on information by echoing the values

      This page is a mess, the code is everywhere even as a .php page

      <?php 
      
      error_reporting(E_ALL);
      error_reporting(-1);
      
      $servername = "localhost";
      $username = "cjdc";
      $password = "";
      $dbname = "";
      
      // Create connection
      $conn = new mysqli($servername, $username, $password, $dbname);
      
      $row_cnt = $conn->num_rows;
      
      $i = "SELECT Ip FROM NewAccount WHERE Id=$row_cnt";
      
      $ipt = $_SERVER['REMOTE_ADDR'];
      
      if ($ipt == $i) {
      $name = "SELECT Name FROM NewAccounts WHERE Id=$row_cnt";
      $age = "SELECT Age FROM NewAccounts WHERE Id=$row_cnt";
      $gender = "SELECT Gender FROM NewAccounts WHERE Id=$row_cnt";
      }
      ?>
        greenace92 wrote:

        I would like to think that the likely-hood of two people creating an account from the same shared network ip addres is low to none

        Actually, it can be quite high because IP addresses, at least IPv4, are scarce enough that they may be reused. For example, I have been IP banned on Wikipedia, not because of anything I did, but because I happened to be assigned the same IP address as some vandal who did a nasty job a short while earlier.

        greenace92 wrote:

        I am counting on the auto-increment function

        If you are running a second query to retrieve the last row ordered by id rather than retrieving the last inserted id on the same database connection using mysqli::$insert_id, then you can run into a race condition if multiple users sign up at the same time.

        greenace92 wrote:

        the person is matched by the ID number assigned to him/her and then their IP address that they used to initially start the account creation process.

        If you already know the id then there is no need to match by IP address as the id is unique.

        greenace92 wrote:

        It is a two part process because I wanted them to simply enter their name, age and gender then "create account"

        I suppose I could just do it all at once but part of the process is showing their information on a display and they can see their name on something and have the ability to decide if they like it or not

        Don't worry, having a multi-stage form wizard process is not a problem. It is just more work.

        This is unnecessary as the variables are already "global":

        global $name, $age, $gender ;

        You might use the global keyword within a function instead to declare that the variable should have global rather than function scope, but then generally we would avoid such declarations.

        This is wrong:

        $name = mysql_real_escape_string($name);
        $age = mysql_real_escape_int($age);
        $gender = mysql_real_escape_string($gender);

        mysql_real_escape_string belongs to the legacy MySQL extension. Since you are using the MySQLi extension, the correct function is mysqli::real_escape_string. You have your database connection object named $conn, so it should be:

        $name = $conn->real_escape_string($name);
        $age = $conn->real_escape_int($age);
        $gender = $conn->real_escape_string($gender);

        However, I suggest that you use prepared statements instead. The idea is to create a prepared statement from your SQL statement, bind the variables as parameters, then execute the prepared statement. This way, the parameter binding takes care of the escaping.

          Thank you for rigorously responding to my questions

          I had others tell me about the race condition, I'm not sure how else to solve this problem

          I would like to think that physically it is impossible for two different people to submit at the same time, not in terms of physical ability but rather latency / mechanical delay

          Why would mysql_real_escape require access ? eg. I received an access denied (using passwrod: NO)

          What is a Fatal error? (besides saying it isn't working)

          Thanks again for your thorough responses

            ...to retrieve the last row ordered by id rather than retrieving the last inserted id...

            What is the difference?

            I used the count function to match that with the auto-increment ID, seems redundant (is)

              I'm sorry to directly use you as a source of answer

              Feel free to stop responding

              I also have another problem of undefined indexes

              I came across isset

              if(isset($POST['notify_box'])){ $notify = $POST['notify_box']; }

              This is a sample code, I'll have to read the documentation but in general what should a value be set as, it could be said that it is dependent but should I always have null as default?

                greenace92 wrote:

                I had others tell me about the race condition, I'm not sure how else to solve this problem

                I would like to think that physically it is impossible for two different people to submit at the same time, not in terms of physical ability but rather latency / mechanical delay

                The problem with two different people submitting at the same time is not about them submitting at the exact same instant. Rather, it is the fact that you have two actions per submission: you insert the details for the user (let's call this action A1 for user A), then you retrieve the details for the second step in the registration process (let's call this action A2 for user A). So, if you have users A and B, that submit one after the other with a sufficient time delay, you end up with A1 A2 B1 B2. This is great, because when doing A2 you will get the expected user count, and likewise for B2. But if they submit at roughly the same time, you could end up with A1 B1 A2 B2. In this case, both A2 and B2 will use the same user count, i.e., you will end up saving the second stage registration for A into the record for B, which is obviously a Bad Thing.

                If you were doing a single stage registration and somehow need to access the id for the user after insertion, you can use mysqli::$insert_id. Since this is done on the same database connection, you will get the correct id even if another user had registered in the meantime. However, since you are going to do a query for the user id on the next page, you cannot do this. Rather, what you can do is to save the user's id in a session immediately after the first stage of registration, then read that user id from the session on the next page.

                greenace92 wrote:

                Why would mysql_real_escape require access ? eg. I received an access denied (using passwrod: NO)

                DO NOT USE ANY FUNCTION THAT BEGINS WITH mysql_. If you have such a function call in your code, it is wrong. Absolutely, definitely, completely, utterly WRONG.

                Now, if you're asking why mysqli_real_escape_string, or in its object oriented form, mysqli::real_escape_string, requires the database connection: it is stated in the PHP manual entry that I linked to in my previous post, i.e., "Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection" (emphasis mine). Failure to take that into account can leave you open to creative SQL injection attacks.

                greenace92 wrote:

                What is a Fatal error? (besides saying it isn't working)

                An error from which the PHP interpreter cannot recover and hence continue interpreting the script.

                  You seem to lack an understanding of basic PHP syntax. It's important to realize that SQL code is not part of PHP syntax and must generally be specified as strings in your PHP code. A good IDE (Integrated Development Environment) can really help you find problems with your code. Consider using something like PHPStorm, Netbeans, Eclipse for PHP, etc.

                    I don't I must not comprehend English or something

                    I don't get how this solves the problem of some random user just pulling up the last person's data before the other person (as you stated with the AB example)

                    Rather, what you can do is to save the user's id in a session immediately after the first stage of registration, then read that user id from the session on the next page.

                    Is it like a POST thing? The ID is carried over by POST?

                      I think I get it, I drew some pictures (pictures help)

                      Well this doesn't actually help as it turns out

                      I'm going to try and tackle the parsing / getting php to actually work problem first

                      Wow this place is like the holy water of antichrist for photos, Jesus, I tried so many ways to get the photo to just display rather than be a link.

                      WP_20141209_003.jpg
                        greenace92 wrote:

                        I don't get how this solves the problem of some random user just pulling up the last person's data before the other person (as you stated with the AB example)

                        Is it like a POST thing? The ID is carried over by POST?

                        The idea is that a session has a session id and state associated with the session. The session id and state is stored server side, e.g., in a file, a database table, a Redis store, etc. The session id is also stored client side, e.g., in a browser cookie or less ideally passed along with the URL query string (and hence it is like POST, but actually is GET). This way, the server can retrieve the correct session state from the client by matching the session id. Once it has retrieved the session state, it can get the user id that was stored in the session. With this user id, your PHP script can thus identify the user for database queries.

                        For more information on sessions, read the PHP manual on sessions.

                          That may be exactly what I am looking for, thank you very much as always

                          I'll be sure to mention you guys (collective for different forums) in the acknowledgment page

                          This isn't to say I won't be back

                          And the website isn't about adult content but if you don't want to be mentioned I won't

                            Write a Reply...