0

I'm making a movie rating website for a project and how to do the rating system has left me at a blank. Please let me know of a proper way to this if you know.

This gets the movie number from the url and displays the relevant information in the page

<body>
<?php
global $conn;
$conn = mysqli_connect('localhost','root','','filmsdb');

function show()
{
global $film;
global $conn;
$film = $_GET['fm'];


$sql = "SELECT * FROM movies WHERE m_No='$film'";
$ok = mysqli_query($conn,$sql);

$data = mysqli_fetch_array($ok);
$c_r= $data[8];
$c_rc= $data[9];

?>
//displays the movie information and uses radio buttons to get user rating

Then this lets the user rate the movie

<?php

}


function act1()
{
if(isset($_POST['rsub']))
{
    global $film;
    global $conn;

    $rate = $_POST['rate'];

    $sqlr= "UPDATE movies SET rating=rating+$rate, rate_count=rate_count+1 WHERE m_No='$film'";
    $output = mysqli_query($conn,$sqlr);
}

if($output==1)
{
    echo 'Data Stored';
}
else
{
    echo 'Data Not Stored ';
    echo mysqli_error($conn);
}
}
$conn = null;
?>
</body>
</html>

when only the first function is being used, it works, but when I try to use the rating system, this error comes in the browser, mysqli_query() expects parameter 1 to be mysqli, null given... Any idea on a workaround for this?

  • 4
    [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)*** Learn about [prepared](http://en.wikipedia.org/wiki/Prepared_statement) statements for [MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! [Don't believe it?](http://stackoverflow.com/q/38297105/1011527) – Jay Blanchard Feb 01 '17 at 13:54
  • 1
    You defined a function for inserts, but I don't see where you call that function – Duane Lortie Feb 01 '17 at 13:59
  • Have you checked in the error log? – M. Eriksson Feb 01 '17 at 14:02
  • ` global $film;` $film does not exist any more - it was only in the previous page. That execution has finished, you've started a new execution. You need to pass the film ID back to the second script from the HTML. – ADyson Feb 01 '17 at 14:04
  • Using `$this->conn = $conn;` in a function (and not a class method) should throw an error. – M. Eriksson Feb 01 '17 at 14:04

1 Answers1

0

Your issue is that the two variables you're relying on with the DB connection, $conn and $film, do not exist when the page has posted back the user rating data.

Your application's lifecycle goes like this:

1) User makes initial request. PHP starts and runs the first code block, it echoes some values to the page, page is returned to the user. Once the page is returned, the request is complete and PHP stops executing. All variables declared and in memory are lost because the process has stopped running.

2) The page returned from the PHP script arrives in the user's browser. User enters their rating and posts the data back to the server. This constitutes an entirely new request.

3) The new request arrives at the server. PHP starts up again. The web is inherently stateless, so by default it remembers nothing of the previous request. Certainly not the names or values in any in-memory variables - the process that contained them died long ago and has no association with the new one.

Therefore, if you have any values that you need to use again in PHP for the second request, you can either create them again, or receive them in the request data, or the first PHP script must have stored them somewhere persistent that you can retrieve them from, such as a session variable or cookie, or database.

It's not clear from your posted code, but presumably in the second request the function act1() gets called somehow and tries to insert the data into the database. It fails because neither $film or $conn have any values in them in this new request.

I suggest you solve it like this:

1) Create your connection object again, this is easy, and you need to re-connect to MySQL for this request anyway.

2) the film you're rating should be passed back from the browser in the form data.

This is the first script, to get the initial film data and render the ratings form to the page.

//re-usable function to connect to DB. Maybe move this out to a separate file so all pages can use it.
function getDBConn() {
  return mysqli_connect('localhost','root','','filmsdb');
}

function show()
{
  $conn = getDBConn();
  $film = $_GET['fm'];
  $sql = "SELECT * FROM movies WHERE m_No='$film'";
  $ok = mysqli_query($conn,$sql);
  $data = mysqli_fetch_array($ok);
  $c_r= $data[8];
  $c_rc= $data[9];
  $conn = null;
}

Your latest update doesn't show the form but I'm going to assume it's something like this, with an additional film hidden field. There should be suitable form tags around it as well.

<input type="radio" value="1" name="rate">
<input type="radio" value="2" name="rate">
<input type="radio" value="3" name="rate">
<input type="radio" value="4" name="rate"><input type="radio" value="5" name="rate">
<input type="hidden" name="film" value="<?php echo $film;?>"/>
<input type="submit" value="Rate" name="rsub">

Now is the second script, to be run when the rating data is submitted. You haven't shown how act1() is called but I'll assume you've got that covered.

function act1()
{
  if(isset($_POST['rsub']))
  {
    $film = $_POST['film']; //get the film ID from the submitted form
    $conn = getDBConn(); //assuming this script is in the same .php file as the first block, otherwise you'll need to move getDBConn into a separate php file and then include the file in each script.

    $rate = $_POST['rate'];
    $sqlr = "UPDATE movies SET rating=rating+$rate, rate_count=rate_count+1 WHERE m_No='$film'";
    $output = mysqli_query($conn, $sqlr);
  }

  if ($output==1)
  {
    echo 'Data Stored';
  }
  else
  {
    echo 'Data Not Stored';
    echo mysqli_error($conn);
  }

  $conn = null;
}

P.S. I know it's just an example project, but if you make a real-life site please heed the comments above re SQL injection, and don't let your applications and websites log into your DB as "root" either - give them only the privileges they actually need.

ADyson
  • 57,178
  • 14
  • 51
  • 63