Problem displaying an age based on a dateOfBirth mysql timestamp
I've got a site with user profiles. On the home page I am trying to show little summaries of each person's profile. This summary includes the name of the person, the gender and the age of the person.
<ul>
{section name=i loop=$person_list}
<li><a href="user_detail.php?id={$person_list[i].id}">{$person_list[i].username}, {$p开发者_Python百科erson_list[i].gender}, {$age[i]}
{/section}
</ul>
I previously used a foreach loop to run through them, but I need the index to also show the display age calculated in the index.php file.
if (isset($_GET['name']) && isset($_GET['gender']))
{
$name = $_GET['name'];
$gender = $_GET['gender'];
}
else
{
$name = "";
$gender = "";
}
define("PERSONS_PER_PAGE", 10);
if (isset($_GET['offset']))
{
$offset = $_GET['offset'];
}
else
{
$offset = 0;
}
list($person_list, $num_persons) = get_persons($name, $gender, $offset, PERSONS_PER_PAGE);
$ages = array();
for ($i = 0; $i < count($person_list); $i++)
{
$ages[$i] = age($person_list[$i].$dateOfBirth, time());
}
$smarty = new Smarty;
$smarty->assign("name", $name);
$smarty->assign("gender", $gender);
$smarty->assign("persons_per_page", PERSONS_PER_PAGE);
$smarty->assign("interests", $interests);
$smarty->assign("offset", $offset);
$smarty->assign("num_persons", $num_persons);
$smarty->assign("person_list", $person_list);
$smarty->assign("ages", $ages);
$smarty->display("index.tpl");
Don't worry too much about the $offset and PERSONS_PER_PAGE, that's only used for pagination.
My age function looks like this:
function age($birth)
{
$birth_date = new DateTime();
$birth_date = $birth;
$birth_date->setTimestamp($birth);
$now = time();
$now_date = new DateTime();
$now_date->setTimestamp($now);
$interval = $birth_date->diff($now_date); // $interval is a DateInterval
$age = $interval->y; // number of years in the interval
return $age;
}
Additionally, in case it's relevant; my get_persons function looks like this:
function get_persons($name, $gender, $offset, $persons_per_page)
{
$connection = mysql_open();
$query = "SELECT SQL_CALC_FOUND_ROWS id, username, gender, dateOfBirth FROM Person";
if ($name && $gender)
{
$query .= " WHERE name like '%$name%' AND gender like '%$gender%'";
}
$query .= " order by id";
$query .= " LIMIT $offset, $persons_per_page";
// print "$query<br>\n";
$result = mysql_query($query, $connection) or show_error();
$r = mysql_query("SELECT FOUND_ROWS()", $connection) or showerror();
$r = mysql_fetch_array($r);
$num_entries = $r[0];
$entries = array();
$person_list = array();
while ($person = mysql_fetch_array($result)) {
$person_list[] = $person;
}
mysql_close($connection) or show_error();
return array($person_list, $num_entries);
}
and the table for a person looks like this:
create table if not exists Person
(
id int not null auto_increment primary key,
username varchar(10) not null,
name varchar(40) not null,
gender varchar(1) not null,
dateOfBirth timestamp not null,
email varchar(40) not null
);
This produces the following error:
Notice: Undefined variable: dateOfBirth in /net/homes.ict.griffith.edu.au/export/home/s2737451/public_html/wp/labs/lab5/index.php on line 39 Fatal error: Call to a member function setTimestamp() on a non-object in /net/homes.ict.griffith.edu.au/export/home/s2737451/public_html/wp/labs/lab5/includes/defs.php on line 167
Thanks in advance, I really need help on this :(
I think that prodigitalson solved your problem, but there are some miscellanous suggestions for your code:
Your SQL query is vunerable to SQL Injection attacks. This is because you are directly inserting user input (GET parameters) into your SQL query string--a big NO NO. For string values, you should use a string escape function, which ensures the string is inserted safely into the query. For MySQL, use the
mysql_escape_string()
function:$query .= " WHERE name like '%" . mysql_escape_string($name) . "%' AND gender like '%" . mysql_escape_string($gender) . "%'";
For numeric values, you should check to make sure the user entered a number and not something else like letters. You probably want
$offset
to always be a positive number, so you can use thectype_digit()
function to make sure the variable contains only number characters (0-9). The value of$persons_per_page
is hard-coded in your script, so you don't have to worry about it.if (!ctype_digit($offset)){ //set to a default value if it's not a positive integer $offset = 10; } $query .= " LIMIT $offset, $persons_per_page";
You can simplify the code that calculates the number of person entries that were returned. Make use of the
mysql_num_rows()
function:$num_entries = mysql_num_rows($result);
Update:
I tried that but it still gave me the error:
Fatal error: Call to a member function setTimestamp() on a non-object in /net/homes.ict.griffith.edu.au/export/home/s2737451/public_html/wp/labs/lab5/includes/defs.php on line 167
I think that is because youre overwriting your DateTime object:
$birth_date = new DateTime();
$birth_date = $birth; // you overwrite the instance of DateTime you created with another value
$birth_date->setTimestamp($birth);
should be:
$birth_date = new DateTime();
$birth_date->setTimestamp($birth);
Like the error says you try to use the variable $dateOfBirth
when it hasnt been defined:
$ages[$i] = age($person_list[$i].$dateOfBirth, time());
I think th issue is you have confused your smarty and php syntax... that line should probably be:
$ages[$i] = age($person_list[$i]['dateOfBirth'], time());
On another note why do you use a seperate array for age why not just add that element to the array of values for each person?
foreach($person_list as $i => $person)
{
$person_list[$i]['age'] = age($person['dateOfBirth'], time());
}
or you can do it by changing your sql command:
function get_persons($name, $gender, $offset, $persons_per_page)
{
$connection = mysql_open();
$query = "SELECT SQL_CALC_FOUND_ROWS id, username, gender, (YEAR(NOW())-YEAR(dateOfBirth)) as age FROM Person";
if ($name && $gender)
{
$query .= " WHERE name like '%$name%' AND gender like '%$gender%'";
}
$query .= " order by id";
$query .= " LIMIT $offset, $persons_per_page";
$result = mysql_query($query, $connection) or show_error();
$r = mysql_query("SELECT FOUND_ROWS()", $connection) or showerror();
$r = mysql_fetch_array($r);
$num_entries = $r[0];
$entries = array();
$person_list = array();
while ($person = mysql_fetch_array($result)) {
$person_list[] = $person;
}
mysql_close($connection) or show_error();
return array($person_list, $num_entries);
}
精彩评论