broj1 356 Humble servant Featured Poster

This error is probably comming from this:

$user_id=mysql_real_escape_string($_POST['user_id']); 

If so, the $_POST array probably does not contain an element with the key user_id. The reeasons could be:

you either have not checked the user ID checkbox. Solution: check for existence of the element in post:

if(isset($_POST['user_id'])) {
    // if user ID exists, asign it to the variable
    $user_id=mysql_real_escape_string($_POST['user_id']);
} else {
    // otherwise do whatever is appropriate
    echo 'User ID is missing';
}

or the user ID checkbox might have other name than user_id. Chek the script that contains the form.

It is actually a good idea to check for existence of all the $_POST array elements before using them.

broj1 356 Humble servant Featured Poster

OK. If it works (no more problems), please mark this as solved.

broj1 356 Humble servant Featured Poster

In addition to that:

Spaces in column names are allowed in mysql but are bad practice in my opnion. The same goes for associative array keys. To avoid possible errors and ensure portability my recommendation is: use undersoces or camelCase instead of spaces for db column names, array keys and variable names.

broj1 356 Humble servant Featured Poster

Variable names can not contain spaces.

$fmcg application=mysql_real_escape_string($_POST['fmcg application']); 

Replace spaces with underscores ($fmcg application -> $fmcg_application)

broj1 356 Humble servant Featured Poster

If I kept the checkbox style, is there a way to make it invisible until the user until they want to see them?

Make them hidden (style="visibility:hidden;") and a button somewhere that says something like 'Display delete checkboxes' and a javascript (called by onclick event) to change the visibility of all checkboxes to visible.

broj1 356 Humble servant Featured Poster

Are you sure that you will get better user experience this way? If you let users delete each post without asking them for confirmation first thea are at risk deleting too many posts to quickly. If you ask them for consfirmation at each post they wish to delete you will make them click a lot (it is better to get the user click the checkboxes, press the delete button and ask for confirmation for all the selected posts to be deleted). This is just my opinion, others might dissagree.

If you want to use a link (or any html element) to trigger deletion you have two ways:
- using javascript onclick event and deleting with ajax call to a php script (recommended, but think about confirmation)
- using a querystring with the id of the post to be deleted (not recommended). This technique is highly discouraged since poses a big security issue. The query string is easily changed so deleting all posts is trivial.

broj1 356 Humble servant Featured Poster

There are many tutorials out there but they might vary in completeness since they often omit some parts to emphasizes others. But your question is spot on. If I got it right you are asking about what to do with the posted values to use them securely.

The trim is actually a good function to get rid of extraneous spaces in before and after the actual text since the user might not be aware of them and they might cause some trouble. But more important is to escape and sanitize the data sent form the form.

The functions you will use depend on the context the value goes to. If you intend to store the value to a database, you tipically escape it (e.g. using mysqli_real_escape_string). If the value goes to the URL then you use urlencode function. If you stick the value into html use htmlspecialchars function etc.
You also have php filters you can use or filter_var.

And also you can also add your custom validating functions (e.g. for checking local phone numbers).

broj1 356 Humble servant Featured Poster

The thing is that you have name attributes for your hidden fields the same for every row so the $_POST array contains only teh last row (last assigned name attributes). You should give the name attributes in each row a unique identifier that is linked to the row in a database. An id field would be the best for this but I am not sure whether you have one.

While I was writing this your code miraculously dissapeared so I can not comment further.

broj1 356 Humble servant Featured Poster

It is a warning not an error, the script gets executed anyway but it just complaining that the coding does not follow the strict rules. I think if you change it to the code below you should be fine. In the production version turn off the display of warnings and errors.

$temp = array_keys($websites_array);
$websites_array_last_id = end($temp);
broj1 356 Humble servant Featured Poster

I tested the code, hopefuly got to grips with it and came up with my solution with no need for session. See the comments.

<?php
// ****** ONLY FOR TESTING

include 'db_connect.php';

// you probably get this from GET
$user_id = 1;

// ******

// get the ID of url the user saw the last
$q = "SELECT url_id FROM views WHERE user_id=$user_id";
$res = mysql_query($q);
$row = mysql_fetch_assoc($res);

// if there is a record for this user assign it to $previous_id
if(isset($row['url_id'])) {

    $previous_id = $row['url_id'];

// if there are no records for this user assign 0 to $previous_id
// which means the user has not viewed any websites yet
} else {

    $previous_id = 0;
}

// this array will hold all the url IDs that can be displayed to the user
$websites_array = array();

// get all the IDs that can be shown to the user
$q = "SELECT id, url FROM websites WHERE userid != $user_id ORDER BY id";
$res = mysql_query($q);
// fill the $websites_array with IDs
while($row = mysql_fetch_assoc($res)) {

    $id = $row['id'];
    $websites_array[$id] = $row['url'];
}

// if there are no urls in the database, do something
if(!isset($websites_array) || empty($websites_array)) {

    die('No web sites to show!');
}

// the last ID in the array (to know when to start from the beginning)
$websites_array_last_id = end(array_keys($websites_array));

// if previous ID is the last ID in the array or is not existing
// start with the forst URL in the array
if($websites_array_last_id == $previous_id || …
broj1 356 Humble servant Featured Poster

And the same goes for cookie values. Sanitize them before you use them.

broj1 356 Humble servant Featured Poster

You have to validate/sanitize input values whenever you either store them in a db or use them in javascript, HTML, CSS, email or any other possible context. If you forgot to do it you risk your app being compromited by SQL injection, XSS attack and similar. Sanitizing means basically escaping or replacing the characters that are unwanted in a particular context like:

  • if you intend to store user entered data into database then most unwanted character is ' (single quote). If you forget to escape it the bad guy can enter code that will change your SQL statemnt in a way that you do not want.
  • if you intend to use user entered data in your html then for example you do not want characters < and > and sometimes & get into html since they can be used to insert harmful client side script code into html
  • etc...

See nice articles here and here and google for sql injection, XSS, html injection...

broj1 356 Humble servant Featured Poster

Why do you have a condition userid !=$user_id in your query? I do not get that.

Anyway, just a guess since I am not sure whether I undertood the problem corectly:

// first get the last ID so you know when to switch for the first id again
// please note that DESC has been used
// LIMIT 1 is enough, no need for LIMT 0,1
$query ="SELECT id FROM websites where userid=$user_id ORDER BY id DESC LIMIT 1";
$last_id = ...

// if $_SESSION['current_id'] does not exist or if it is equal to last id
// then read the first record
if(!isset($_SESSION['current_id']) or $_SESSION['current_id'] == $last_id)
{
    // this query will select the record with the lowest id, presumably the first record
    $query ="SELECT * FROM websites where userid =$user_id ORDER BY id ASC LIMIT 1";

// in other cases read next record
} else {
    // this query will read the record just after the current id
    $query = "SELECT * FROM websites WHERE id > {$_SESSION['current_id']} AND userid =$user_id ORDER BY id ASC LIMIT 1";
}
broj1 356 Humble servant Featured Poster

So do you get fleet number from the fleetNumbers table? What is the structure of this table? This table has not been mentioned in your previous posts at all.

broj1 356 Humble servant Featured Poster

How to display next website after viewed last time when $_SESSION is reset?

When the session is reset (i.e. browser is closed) you loose that information. If you want to keep it you have to store it somewhere. One option is on server (in a database or in a file) other option is on users machine (a cookie). It is up to you to decide which one is more convenient.

When records end from table websites it gives error,
Notice: Undefined variable: url_id
Notice: Undefined variable: url

Can you find out which line the notices are being issued? You use these variables in many places.

broj1 356 Humble servant Featured Poster

This is a bit strange. You populate the select element with numbers from vehicle_info table and then store the chosen number into the same table. You should have a source for the select element somewhere else (maybe some other table) otherwise you keep running in circles. Or have I missunderstood something?

broj1 356 Humble servant Featured Poster

use mysql_real_escape_string() function to escape characters in all input fields. Not just to enable people to enter quotes but also to prevent evil people to enter harmfull code.

$title = mysql_real_escape_string($_POST['title']);
$content = mysql_real_escape_string($_POST['content']);
$creator = mysql_real_escape_string($_POST['creator']);

Mind you the connection to mysql has to be established in order to use this function. BTW: It is recommended to switch to mysqli extension.

broj1 356 Humble servant Featured Poster

Save score for each question in a session where the key for an array is the question ID.

// store current score in an array of scores in a session
$_SESSION['score'][$id] = $points_for_current_answer;

Whenever you want to display the score, just add scores together:

$your_score = array_sum($_SESSION['score']);
broj1 356 Humble servant Featured Poster

should i keep these in while loop??? to increment after every question?

I don't think so. Since every question is on separate page the the evaluation happens only once on each page (while the user is on that page).

and how i can get total number of questions from DB?

By querying questions using COUNT(*).

$query = 'SELECT COUNT(*) FROM questions';

If each user gets the same number of questions this is enough. If there are other conditions use WHERE clause like:

$query = 'SELECT COUNT(*) FROM questions WHERE courseid=' . $course_id;
broj1 356 Humble servant Featured Poster

Thanks broj1

No worries. But I think I have contributed the least in this thread :-).

broj1 356 Humble servant Featured Poster

You have to know total maximum score which is total number of questions * 10 (I guess). Then when you have a score at particular question you just divide it with the total and multiply by 100. The result is the total percentage.

// ie you have 20 questions
$total_questions = 20;
$points_for_one_answer = 10;
$total_score = total_questions * $points_for_one_answer;
$score_percent = $score / $total_score * 100;

echo "your current score is $score_percent %";

$score is current score and I guess it is kept in session. It would be a good idea to display the number of answered questions and number of all questions:

echo "You have answered $number_of _answered questions out of $total_questions.";
broj1 356 Humble servant Featured Poster

It is a lot of code to have a look at and a lot of includes which makes it very difficult to test. Also the structure of tables is not shown. And even if it were it is quite a project for someone to help here.

In principle I would have something like following tables:

Table: questions
Field          Type     Description
------------------------------------------------
id             int      ID
question       varchar  Question text
question_type  varchar  Question type (multichoice | true/false)
correct_answer tinyint  No of correct answers from possible_answers table

Table: possible_answers
Field          Type     Description
------------------------------------------------
q_id           int      ID of question from questions table
q_no           tinyint  No of possible answer for that question (e.g. 1, 2, 3, 4 ...)

Table: users
Field          Type     Description
------------------------------------------------
id             int      user ID
... (other user data)

Table: user_score
Field          Type     Description
------------------------------------------------
user_id        int      ID of a user (from the users table)
question_id    int      ID of a question (from the questions table)
answer_no      tinyint  No of answer the user chose (from the possible_answers table)

Now you can built all your logic arround these tables using correct queries:

  • to display a question
  • to display possible answers
  • to store chosen answer
  • to check whether the answer is correct
  • to calculate the score

I hope that helps.

broj1 356 Humble servant Featured Poster

And about php.net. This is definetly the best source of information but I understand that is sometimes hard to comprehend since it is not written for beginners. But if you get used to it and its structure (syntax, examples, user comments) it will give you the most and up to date information. Just keep on using it and you will get used to it.

broj1 356 Humble servant Featured Poster

mysqli is not updated/improved edition of MySQL but a PHP extension to access MySql. You can access MySql database with either mysql or mysqli extension (or PDO) but you are always accessing MySql database. mysqli is newer, will be supported in future and has more functionalities (like prepared statements).

broj1 356 Humble servant Featured Poster

Plenty of mysqli examples on Google like this one.

Ajax you need to change the contents of a webpage (like div or span) without refreshing the page. An example is a basket content in a web shop.

broj1 356 Humble servant Featured Poster

Firstly you explained the MySQLI plugin to me. Then you said I should also learn AJAX. Why is all of this necessary?

Well, it is not necessary, but dynamic web application usually stores to and uses data from a database and MySql is very popular database (and free). You can choose to use any other database (Oracle, MSSql, you name it), it is up to you (hopefully you have a reason to choose so).

Ajax is a way of using Javascript and XML (or PHP or JSON instead) that improves user experience. It is a very good idea to get familiar with it since once you do serious development you will need it. It is not very hard and you can use libraries like jQuery to make the most of it without really spending to much time on it.

If we replace lines 4 and 5 (extremely indented) with MySQL retrieval code, it will work right?

Yes, as long as you do not make any syntax or other errors :-). It is perfectly right to pull data from database, store it in variables and use it later in a script.

broj1 356 Humble servant Featured Poster

OK, so if you do not intend to carry on in this thread, please mark it as solved.

broj1 356 Humble servant Featured Poster

I do not quite understand what other questions are. Can you state them clearly?

broj1 356 Humble servant Featured Poster

Today is my birthday. :-)

All the best :-)

How to retrieve only one record instead of retrieve all of them?

The condition must be such that returns only one record:

$query = 'SELECT Age FROM tablename WHERE condition=something';

Have a look at http://phpacademy.org/ which will be easiest way to learn.

The book I used a couple of years ago was PHP6 and MySql Bible. It is avaliable on Amazon but I it is not cheap and I am not sure if it is simple.

broj1 356 Humble servant Featured Poster

I was away until just now. OK, so you will try it other way. My suggestion is that you first outline the logic with comments like:

// check if the user is authorised, if not, redirect

// if first question read the first question, correct answer and possible answers
// otherwise read the next question, correct answer and possible answers

// if user submitted the answer to the previous question store the answer

// compare the answers    
// if the answer was wrong notify the user

// display the page

// ...

Once you have logic done start coding. It will be easier that way and to upgrade logic later. And separate the logic and the html output as much as possible.

broj1 356 Humble servant Featured Poster

OK, you posted while I was checking your previous code.

now i want to check which question is right and which is wrong

Well, everything depends on what you want to do. If the question is wrong, should it stay on the same question or move to the next? Where do you want to keep the answers, in a database or in session (they will get lost once the user logs out)? It is good to have some sort of a blueprint before you start coding.

broj1 356 Humble servant Featured Poster

when i write echo $query it says undefined variable

Ups, I just realized that you do not use $query to store the query (as I suggested) but you pass it as a string to mysql_query. Well, I have to live right now but I'll come back tonight. In meanwhile you can assign a query to a variable and echo it:

instead of:

$result = mysql_query("SELECT * FROM courses WHERE (id=".$cid.")");

do:

$query = "SELECT * FROM courses WHERE (id=".$cid.")";
echo $query;
$result = mysql_query($query);
broj1 356 Humble servant Featured Poster

The $result does not show your query, echoing it is pretty much useless. It holds the resource - a special PHP type. So please do as I suggested in my last post. Echo the queries and test them in phpmyadmin.

and then if i go back to previous page from browser it shows nothing...is that because of sessions?

It could be true, I am not sure I should do a test. There are other mechanisms you could use instead of sessions to transfer the current id: a hidden field, a querystring or even a cookie. But session is the most secure way since the visitor can not change the values and skip to other questions.

broj1 356 Humble servant Featured Poster

And also I noticed that the query for last id on line 108 is wron. It shoult be ordered in descending order (DESC) to get the last id.

$result1 = mysql_query("SELECT id FROM questions WHERE (evaluationid=".$evaluationid.") ORDER BY id DESC LIMIT 1 ");
broj1 356 Humble servant Featured Poster

One thing you can do is quickly debug the query. Put this code on line 71 (and remuve the echo $result code):

echo $query;

This will display your query on each new page and you can check in phpmyadmin whether the values are correct. You can do this for all queries and other values a s well.

broj1 356 Humble servant Featured Poster

I do not have time to test your code right away (hopefully I can do it tonight at home). First thing I can't find is session_start() which should be on the beginning of the script. You must add it in order to usesessions.

broj1 356 Humble servant Featured Poster

Ok, I am new to MySQL. I'm just 15.

Best time to start learning :-)

1.What is mysqli?

mysqli is an extensions to the core functionality of PHP to enable you to deal with mysql database. See the link in my previous post (php.net is THE source you want to bookmark).

2.Your code mentions a variable named result which is never created. The code won't work!

$result is being created in line 13 of my code and stores the result of the query (a result object if succesfull or false if unsuccessful). If the code does not work there might be errors somewhere. Have you entered correct info to the connect function? Do you have any error messages?

3.As I mentioned, I don't know anything. So do I have to learn Asynchronous JavaScript and XML?

Yes, if you intend to do serious web devlopment. You should know javascript to some extent but not necessarily in depth. You can use jquery or some similar library that hides complexity for you, instead. XML is not compulsory since JSON is used in number of cases these days. And it is good if you understand the concept of AJAX.

  1. Imagine this situation: There are four divs, each of them are being made in HTML(not a PHP echo command so that they can be stylised in CSS) and stylised in CSS. The fourth one's id is putTextHere. How to put age here?

The divs can …

broj1 356 Humble servant Featured Poster

Yes, you are right. The questions are getting displayed on the same page. This is set in the action attribute of the form:

<form  action='start-course-evaluation-action.php' method='post'>

and could as well be:

<form  action='#' method='post'>

and the above code should be part of this script. You have to add logic to evaluate and/or save the answers to the current question (probbably save them permamnently in a database or temporary in a session upon each submit). The logic should be somewhere on the beginning of the script.

broj1 356 Humble servant Featured Poster

Also have a look at the example here. You can se the process of connecting to db, querying and fetching rows in both procedural and object oriented ways. At some stage it is useful to adopt the object oriented apprpoach and get familiar with since so many frameworks and libraries these days use it.

And here you can read about the difference between the mysql and mysqli extensions an a lot of other interesting stuff about how php works with mysql.

broj1 356 Humble servant Featured Poster

OK, clashed with Utrivedi's post which directs you to the same concept. I would only recomend using mysqli extension instead of mysql since the former is newer and offers more functionalities. Anyway, the approach is the same in both posts.

broj1 356 Humble servant Featured Poster

In a nutshell:

// connect to a database (mysql in this example, using mysqli extension)
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');

// check connection
if (mysqli_connect_errno()) {
    die("Connect failed: " . mysqli_connect_error());
}

// a query for selecting age
$query = 'SELECT Age FROM tablename WHERE condition=something';

// run the query and on success display the row
if ($result = mysqli_query($link, $query)) {

    // fetch row
    $row = mysqli_fetch_row($result);

    // echo the value within the div
    echo '<div id="putTextHere">' . $row[0] . '</div>';

}

// free result set
mysqli_free_result($result);

Now, if the pae already exists and you would like to inject age into existing div then you would have to use Ajax.

broj1 356 Humble servant Featured Poster

Assuming that id is an integer and autoincremented by the DB then the id fields probably increase with every new question and you can use this approach:

Whenever you read and display the question save the id in the session. If there is no id in the session you are displaying the first question otherwise you just go for the next question. Also save the id of the last question so you know when to stop. The rest is documended in the code below (it should be a part of start-course-evaluation-action.php script):

// start the session
session_start();

// if this is the first run of your script
// the id has not been stored in the session yet
if(!isset($_SESSION['current_id'])) {

    // this query will select the question with
    // the lowest id, presumably the first one
    $query = 'SELECT * FROM questions ORDER BY id ASC LIMIT 1';

    // read the row, display the question as in the form as above
    // the form can have action set to self (#)
    ...

    // store the current id in the session
    $_SESSION['current_id'] = $row['id']

    // read the last id so you know when to stop
    $query = 'SELECT id FROM questions ORDER BY id DESC LIMIT 1';
    ...

    // store the last id in the session
    $_SESSION['last_id'] = $row['id'];

// if current id exists in the session you can go and display the next qestion
} else {

    // this query will read the question just after the current id
    // …
broj1 356 Humble servant Featured Poster

Now I get what you want. You do not want to display a contents of one record on one page but a page with a URL which is stored in a record. Is that true? Well, if it is the best way I know would be using iframes which you do. But if the framebreakers on those pages redirect ot original page then as far as I am aware you loose control. I am not aware of a way how to avoid this (actually have no much experience in it). Maybe someone else on this forum knows more about that?

broj1 356 Humble servant Featured Poster

OK, you forgot to mention what type it is. So if it is an integer and autoincreased by the DB then the id fields probably increase as you add records and you can use this approach:

whenever you read and display the record save the id in the session. If there is no id in the session you are displaying the first record otherwise you just go for the next record. The rest is documended in the code below:

// start the session
session_start();

// if this is the first run of your script the id has not been stored in the session yet
if(!isset($_SESSION['current_id'])) {

    // this query will select the record with the lowest id, presumably the first record
    $query = 'SELECT * FROM table_name ORDER BY id ASC LIMIT 1';

} else {

    // this query will read the record just after the current id
    $query = 'SELECT * FROM table_name WHERE id > {$_SESSION['current_id']} ORDER BY id ASC LIMIT 1';
}

// read the row, display it and store the current id in the session
...
$_SESSION['current_id'] = $row['id']

More precise solution would be to have a field with timestamp so you could be always sure that the displayed records follow correctly each other.

Hopefully this is what you wanted to know.

broj1 356 Humble servant Featured Poster

Do you have a primary key or unique field in the table and what type it is? This is cruical for some control of which record to access.

broj1 356 Humble servant Featured Poster

First check in your generated html code whether checkboxes have intended names (chkDel[] and values (the ID of the customer). You can do that by looking at the source in your browser (right button and View Page Source in Firefox).

Then check whether the $_POST contains appropriate values in code 2. You can do this by inserting the following command on say line 9:

die(print_r($_POST, 1));

This will print the content of $_POST values which should contain an array of values of checked checkboxes (and a value for submit button).

But first things first: immediately change your credentials for database access.

broj1 356 Humble servant Featured Poster

You have probably sent some HTML output before session_start() line in your code. Make sure that the session_start() function is on the very beginning of the script. Also make sure there is no space that you are unaware of in the beginning before the <?php ?> block. If there are included files before session_start() they also should not sent HTML output.

You can post your script (or part of it) here for us to see what is the problem.

broj1 356 Humble servant Featured Poster

cheers for all your help mate.
It is much appreciated.

No worries.

One way of doing the updating only the changed values would be as follows (see comments in the code). I added a hidden field in each row to hold the value (same as input) and which can be then compared to see if changed.

<?php
while($row = mysql_fetch_array($result)){

    $text_name = 't-' . $row['id'];
    $hidden_name = 'h-' . $row['id'];
    $value = $row['handicap'];

    echo"<tr>";
    echo"<td>" . $row['ID'] . "</td>";
    echo"<td>" . $row['First'] . "</td>";
    echo"<td>" . $row['Last'] . "</td>";
    echo"<td>" . $row['handicap'] . "</td>";
    echo "<input type=\"text\" name=\"$text_name\" value=\"$input_value\" />";

    // hidden field added here; the value is the same as the input field's value
    echo "<td><input type=\"hidden\" name=\"$hidden_name\" value=\"$input_value\" /></td>";
}
echo"</table>";

echo"<input type=\"submit\" name=\"submit\"/>";
//endwhile;

if (isset($_POST['submit'])) {

    // initialize arrays for the text input values
    // the $text_values array will contain all the values from text input boxes
    // the $hidden_values array will contain all the values from hidden input boxes
    // these values were initially equal for each row; if user changes the value
    // in the input box, the corresponding value in the hidden input will differ
    // which will trigger the update query for that row
    $text_values = array();
    $hidden_values = array(); 

    // now let's go through the $_POST array where:
    // $key is the name attribute of the input box
    // $val is the value of that input box
    foreach($_POST as $key => $val) {

        // if $key starts with …
broj1 356 Humble servant Featured Poster

Use header function at the end. But be careful, no HTML or any other output should be sent before the header function in order for it to work:

header('location:yourpage.php');
broj1 356 Humble servant Featured Poster

This is a bit tricky. Simple thing would be to update all displayed rows (either changed or not changed) but that is a bit redundant:

if (isset($_POST['submit'])) {

    // ditch the submit element from $_POST
    unset($_POST['submit']);

    // loop through values in $_POST and shoot the query for each value
    // (it would be more efficient to use prepared queries here)
    foreach($_POST as $key => $val)
        mysql_query("UPDATE members SET handicap='$val' WHERE id=$key LIMIT 1"); 
    }
}

Above code does to mich work for nothing.

So you have to know which row has been changed. You can do that with a hidden field added to each row. The hidden field would contain the id of the row in it's name and would have a value of the existing textbox. Then when processing form you could compare the text input value with the hidden field value and if they differ update that row. Another approach would be using ajax to update a row upon leaving textbox (using an onblur javascript event). To give you examples I would need more time (and is half past midnight here). So if any other posters do not respond I'll be back tomorrow.