PHP将变量从一个循环传递到另一个循环并在循环外部进行排序

时间:2016-09-14 03:26:02

标签: php

首先,我有一个显示给定用户朋友列表的循环。

$stmt=$db->prepare('SELECT friend1, friend2 
                    FROM list_friends 
                    WHERE (friend1 = :user AND friend2 <> :user) 
                    OR (friend2 = :user AND friend1 <> :user)');

$stmt->bindParam(':user', $username);
$stmt->execute();
$row = $stmt->fetchAll()
foreach  ($row AS $row) {
    if ($row[friend1] !== $username) {
        $friend = $row[friend1]; 
    } else {
        $friend = $row[friend2]; 
    }
    echo $friend;
}

其次我有一系列数组按时间和日期进行比较和排序,然后回显

$stmt=$db->prepare('SELECT * FROM banners WHERE username = :user');
$stmt->bindParam(':user', $friend);
$stmt->execute();
$row = $stmt->fetchAll();

$stmt=$db->prepare('SELECT * FROM favorites WHERE username = :user');
$stmt->bindParam(':user', $friend);
$stmt->execute();
$row1 = $stmt->fetchAll();

$stmt=$db->prepare('SELECT * FROM sites WHERE username = :user');
$stmt->bindParam(':user', $friend);
$stmt->execute();
$row2 = $stmt->fetchAll();

$stmt=$db->prepare('SELECT * FROM social_posts WHERE username = :user');
$stmt->bindParam(':user', $friend);
$stmt->execute();
$row3 = $stmt->fetchAll();

if ($db2->query("SHOW TABLES LIKE 'elfinder_file_".strtolower($friend)."'"
           )->rowCount() > 0
){
$stmt=$db2->prepare("SELECT * FROM elfinder_file_".strtolower($friend)." WHERE mime <> 'directory' GROUP BY time");
$stmt->execute();
$row4 = $stmt->fetchAll();
}


foreach( $row AS $banner_table ) {
    $data[] = array('type' => 'banner', 'time' => $banner_table["time"]);
}
foreach( $row1 AS $favorites_table ) {
    $data[] = array('type' => 'favorite', 'time' => $favorites_table["time"]);
}
foreach( $row2 AS $sites_table ) {
    $data[] = array('type' => 'sites', 'time' => $sites_table["time"], 'site' => $sites_table["url"], 'title' => $sites_table["title"]);
}
foreach( $row3 AS $social_table ) {
    $data[] = array('type' => 'social', 'time' => $social_table["time"], 'thetype' => $social_table["type"]);
}

if ($db2->query("SHOW TABLES LIKE 'elfinder_file_".strtolower($_GET[user])."'")->rowCount() > 0 )
{
    foreach( $row4 AS $photos_table ) {
        $data[] = array('type' => 'photo', 'time' => $photos_table["time"]);
    }
}

function cmp($a, $b)  {
    $ad = new DateTime($a['time']);
    $bd = new DateTime($b['time']);   
    if ($ad == $bd) {
        return 0;
    }
    return $ad < $bd ? -1 : 1;
}
if ($data !== NULL) {
    usort($data, "cmp");
    for($i=(count($data)-1);$i>=0;$i--){
        $tttime = $data[$i]['time'];
        $ttime = new DateTime($tttime);
        $stmt=$db->prepare('SELECT timezone FROM member_credits WHERE username = :user');
        $stmt->bindParam(':user', $username);
        $stmt->execute();
        $row = $stmt->fetch();
        if ($row[timezone] === NULL) { $row[timezone] = 'America/Denver'; }
        $usersTimezone = (new DateTimeZone($row[timezone]));
        $ttime->setTimeZone($usersTimezone);
        $ttimee = $ttime->format('D M j, Y g:i A');
        if($data[$i]['type']=='favorite'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' added a website to their favorites while surfing the exchange.</li>';
        } elseif($data[$i]['type']=='banner'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' added a banner to the banner exchange.</li>';  
        } elseif($data[$i]['type']=='sites'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' added the website &nbsp;<a href="'.$data[$i]['site'].'" target="_blank" style="font-weight:bolder;">'.$data[$i]['title'].'</a>&nbsp; to the traffic exchange.</li>';  
        } elseif($data[$i]['type']=='social'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' has requested a social exchange on '.$data[$i]['thetype'].'.</li>';  
        } elseif($data[$i]['type']=='photo'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' uploaded a photo to their profile.</li>';  
        }
    }
}

我遇到的问题是如果我做了第一个foreach,那么第二个,它只回显来自循环中的最后一个朋友的结果(逻辑上),如果我在第一个包含第二个foreach,它会生成所有每个用户的结果一个接一个,因此所有user1的结果将按时间返回并排序,然后是所有user2的结果,依此类推。

我正在寻找的结果是所有连接在一起的结果列表,然后根据时间返回。

样本结果:

user1 uploaded a photo at 12:00pm
user2 added a banner at 11:00 am
user2 uploaded a photo at 10:00 am
user1 added a favorite 9:00 am
etc.
etc.
etc.

2 个答案:

答案 0 :(得分:0)

使用以时间作为索引的数组,而不是回显结果。收集所有结果并按索引对数组进行排序。

的内容
$li[$ttimee] .= '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' uploaded a photo to their profile.</li>';  

我使用.=所以同时发生的事情不会过度。

答案 1 :(得分:0)

使用嵌套循环:在查询朋友列表的第一个循环中,放置所有代码以获取每个朋友的各种活动,并将这些活动添加到单个数组中。然后,您可以按时间戳对所有结果进行排序。

此外,在您的代码中,$row变量名称会出于不同目的多次重复使用;你将失去你想要坚持的信息。作为一般规则,为了您的程序员和您自己,总是使用有意义的变量名称。 $tttime$ttime$ttimee对读者来说并不友好。

所以代码应该是(没有测试过)的代码:

function cmp($a, $b)  {
    $ad = new DateTime($a['time']);
    $bd = new DateTime($b['time']);   
    if ($ad == $bd) {
        return 0;
    }
    return $ad < $bd ? -1 : 1;
}

$all_activies = [];
$stmt=$db->prepare('SELECT friend1, friend2 
                    FROM list_friends 
                    WHERE (friend1 = :user AND friend2 <> :user) 
                    OR (friend2 = :user AND friend1 <> :user)');

$stmt->bindParam(':user', $username);
$stmt->execute();
$friends = $stmt->fetchAll()

foreach  ($row AS $friends) {
    if ($row[friend1] !== $username) {
        $friend = $row[friend1]; 
    } else {
        $friend = $row[friend2]; 
    }

    /* repeat this block for each activity type */
    $stmt=$db->prepare('SELECT * FROM banners WHERE username = :user');
    $stmt->bindParam(':user', $friend);
    $stmt->execute();
    $banners = $stmt->fetchAll();

    foreach($banner AS $bannners ) {
        $all_activies[] = array('friend' => '$friend', 'type' => 'banner', 'time' => $banner["time"]);
    }
    /* repeat this block for each activity type */


}

if ($all_activies !== NULL) {
    usort($all_activies, "cmp");
    for($i=(count($all_activies)-1);$i>=0;$i--){
        $tttime = $all_activies[$i]['time'];
        $friend = $all_activies[$i]['friend']

        $ttime = new DateTime($tttime);
        $stmt=$db->prepare('SELECT timezone FROM member_credits WHERE username = :user');
        $stmt->bindParam(':user', $username);
        $stmt->execute();
        $row = $stmt->fetch();
        if ($row[timezone] === NULL) { $row[timezone] = 'America/Denver'; }
        $usersTimezone = (new DateTimeZone($row[timezone]));
        $ttime->setTimeZone($usersTimezone);
        $ttimee = $ttime->format('D M j, Y g:i A');

        if($all_activies[$i]['type']=='favorite'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' added a website to their favorites while surfing the exchange.</li>';
        } elseif($all_activies[$i]['type']=='banner'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' added a banner to the banner exchange.</li>';  
        } elseif($all_activies[$i]['type']=='sites'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' added the website &nbsp;<a href="'.$all_activies[$i]['site'].'" target="_blank" style="font-weight:bolder;">'.$all_activies[$i]['title'].'</a>&nbsp; to the traffic exchange.</li>';  
        } elseif($all_activies[$i]['type']=='social'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' has requested a social exchange on '.$all_activies[$i]['thetype'].'.</li>';  
        } elseif($all_activies[$i]['type']=='photo'){
            echo '<li style="padding: 8px 5px 8px 95px;"><span class="date"><b>'.$ttimee.'</b></span>'.$friend.' uploaded a photo to their profile.</li>';  
        }
    }
}

您的代码仍有几个不能反映最佳做法的问题。查询每个活动的时区,不限制活动的结果集等 - 这些都应该得到解决,特别是如果您想将代码投入生产中。