基于dateOfBirth mysql时间戳显示年龄的问题


Problem displaying an age based on a dateOfBirth mysql timestamp

我有一个用户配置文件的网站。在主页上,我试图展示每个人的个人资料的小摘要。这个摘要包括这个人的名字、性别和年龄。

        <ul>                
            {section name=i loop=$person_list}
                <li><a href="user_detail.php?id={$person_list[i].id}">{$person_list[i].username}, {$person_list[i].gender}, {$age[i]}
            {/section}
        </ul>

我之前使用了foreach循环来遍历它们,但是我还需要索引来显示index.php文件中计算的显示年龄。

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");

不要太担心$offset和PERSONS_PER_PAGE,它们只用于分页。

我的年龄函数是这样的:

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;
}

另外,如果它是相关的;我的get_persons函数如下所示:

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);
}

和一个人的表是这样的:

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
);

这会产生以下错误:

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

提前感谢,我真的需要帮助。

我认为prodigitalson解决了你的问题,但是对于你的代码有一些杂乱的建议:

  • 您的SQL查询容易受到SQL注入攻击。这是因为您直接将用户输入(GET参数)插入到SQL查询字符串中——一个大的NO NO。对于字符串值,应该使用字符串转义函数,以确保将字符串安全地插入查询中。对于MySQL,使用mysql_escape_string()函数:

    $query .= " WHERE name like '%" . mysql_escape_string($name) . "%' AND gender like '%" . mysql_escape_string($gender) . "%'";
    

    对于数值,您应该检查以确保用户输入的是数字,而不是字母之类的东西。您可能希望$offset始终是正数,因此您可以使用ctype_digit()函数来确保变量仅包含数字字符(0-9)。$persons_per_page的值在您的脚本中是硬编码的,因此您不必担心它。

    if (!ctype_digit($offset)){
       //set to a default value if it's not a positive integer
       $offset = 10;
    } 
    $query .= " LIMIT $offset, $persons_per_page";
    
  • 您可以简化计算返回的人员条目数的代码。使用mysql_num_rows()函数:

    $num_entries = mysql_num_rows($result);
    

更新:

我试过了,但它仍然给我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/inc­ludes/defs.php on line 167

我认为这是因为你覆盖了你的DateTime对象:

$birth_date = new DateTime();
$birth_date = $birth; // you overwrite the instance of DateTime you created with another value
$birth_date->setTimestamp($birth);
应:

$birth_date = new DateTime();
$birth_date->setTimestamp($birth);

就像错误说你试图使用变量$dateOfBirth时,它还没有被定义:

$ages[$i] = age($person_list[$i].$dateOfBirth, time());

我认为问题是你混淆了你的smarty和php语法…这一行应该是:

$ages[$i] = age($person_list[$i]['dateOfBirth'], time());

另一方面,为什么要使用一个单独的数组来表示年龄,为什么不直接将该元素添加到每个人的值数组中?

foreach($person_list as $i => $person)
{
    $person_list[$i]['age'] = age($person['dateOfBirth'], time());
}

或者您可以通过更改SQL命令来实现:

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);
}