为什么!in_array()无法正常工作?还是我的逻辑有缺陷?

时间:2012-09-28 14:53:48

标签: php arrays simplexml

以下是我尝试做的事情的基本逻辑,似乎并没有起作用。

  1. 循环播放字母数组
  2. 对于每个字母,循环遍历XML,如果程序名称以当前字母开头,并且major不在输出数组中,则输出包含XML中某些数据的链接
  3. 每当输出链接时,将major添加到输出数组中,这样我们就不输出双精度
  4. 问题是即使主要在数组中的行:

    if (!in_array($program->Program, $majors)) {
    

    始终返回true,导致输出双打。

    目前在页面上,在输出的每个链接之后,我还输出整个数组,以便在视觉上确认数组中存在主要内容,以及当您到达主要WBAN的页面底部时,在第一个输出中你可以查看它上面的数组并看到它在数组中不存在所以它输出但是,下一个链接输出也是WBAN,你可以在它上面的数组中看到它已经存在所以if应该返回false而不输出它......

    我的逻辑必须在某个地方存在缺陷 - 我已经尝试过将array_push全部移动并且无法使其正常工作 - 我需要新鲜的眼睛。

    另外 - 如果我错了,请纠正我,但我不能从XML中清除重复的原因是因为完整的XML节点不是重复的 - 只是主要的是。

    例如,这里是XML - 只有Program和MajorDescription会被复制,因此完整的XML节点不会被视为重复?:

    <ProgramList>
        <MajorDescription>WEB ANIMATION AND DESIGN</MajorDescription>
        <Program>WBAN</Program>
        <ProgramLocations>
            <ProgramLocation>
                <Campus>Barrie</Campus>
            </ProgramLocation>
        </ProgramLocations>
        <Term>201310</Term>
    </ProgramList>
    

    完整代码:

    <?php 
    $majors = array();
    foreach ($alphabet as $l){
        $upper = strtoupper($l);                            
    
        foreach ($listxml->ProgramList as $program) {
            $letter = substr($program->MajorDescription, 0, 1);
            if (strcasecmp($letter, $l) == 0) {
                $count1++;
                $noprograms = false;
            }                               
        }
    
        if ($count1 == 0) {
            echo "<div id='$l' class='letter noprograms'>"; 
        } else {
            echo "<div id='$l' class='letter'>";
        }                           
    
        echo "<h2>$upper</h2>";
    
        foreach ($listxml->ProgramList as $program) {                             
            $letter = substr($program->MajorDescription, 0, 1);                
    
            if (strcasecmp($letter, $l) == 0) { 
    
                foreach ($majors as $major){
                    echo "<p>".$major."</p>";
                }                  
                //this is where the problem is - this is always coming back true even if the major is in the array 
                if (!in_array($program->Program, $majors)) {                                    
                    echo "<a href='../program/?major=".$program->Program."' class='programLink'>".$program->Program." - ".strtoupper($program->MajorDescription)."</a> - <a target='_BLANK' href='http://www.ontariocolleges.ca/SearchResults/GEORGIAN/_/N-1z1419r?Ntt=".rawurlencode($program->MajorDescription)."&Ns1=Program_Title_SORT&Ns2=0&Qo=20&SearchWithin=on'>Apply Now</a><br />";                                                                                                           
                    array_push($majors, $program->Program);
                }                                                                       
                $count++;                                   
            }                               
        }
        if ($count == 0) {
            echo "<em class='noprograms'>No Programs</em><br />";
        }
        echo "</div>";                      
        $count = 0;
        $count1 = 0;
    }
    
    if ($noprograms) {
        echo '<div id="noprograms"><em>No results. Try broadening the search filters.</em></div>';
    }
    ?>
    

3 个答案:

答案 0 :(得分:2)

您必须将节点强制转换为字符串值:

if (!in_array((string)$program->Program, $majors)) {

array_push($majors, (string)$program->Program);

这是使用SimpleXML时必须习惯的事情之一;隐式地将变量强制转换为字符串的函数不需要这种特殊处理,但如果你真的是偏执狂,我会建议投射一切; - )

例如,substr()不需要强制转换,因为它希望第一个参数仍然是一个字符串,它会自动转换它。

答案 1 :(得分:1)

<击>

<击>
if (!in_array($program->Program, $majors, true)) {
                                          ^^^^

in_array有一个严格的参数,你应该在处理对象时使用它(就像你一样)。

另一种选择是SplObjectStorage

$majors = new SplObjectStorage;

$majors->containts($program->Program);

$majors->attach($program->Program);

最后是关键变体:

$programName = (string) $program->Program;

isset($majors[$programName]);

$majors[$programName] = 1;

答案 2 :(得分:0)

不确定,但我认为您可能在此部分遇到问题:

foreach ($listxml->ProgramList as $program) {                             
    $letter = substr($program->MajorDescription, 0, 1);                

    if (strcasecmp($letter, $l) == 0) { 

        foreach ($majors as $major){
            echo "<p>".$major."</p>";
        }                  
        //this is where the problem is - this is always coming back true even if the major is in the array 
        if (!in_array($program->Program, $majors)) {                                    
            echo "<a href='../program/?major=".$program->Program."' class='programLink'>".$program->Program." - ".strtoupper($program->MajorDescription)."</a> - <a target='_BLANK' href='http://www.ontariocolleges.ca/SearchResults/GEORGIAN/_/N-1z1419r?Ntt=".rawurlencode($program->MajorDescription)."&Ns1=Program_Title_SORT&Ns2=0&Qo=20&SearchWithin=on'>Apply Now</a><br />";                                                                                                           
            array_push($majors, $program->Program);
        }                                                                       
        $count++;                                   
    }                               
}

对于$listxml->ProgramList中的每个元素,您都会打印所有$majors

你应该尝试把

        foreach ($majors as $major){
            echo "<p>".$major."</p>";
        }

循环foreach ($listxml->ProgramList as $program) {循环。

你也做了两次相同的测试:

foreach ($listxml->ProgramList as $program) {                             
    $letter = substr($program->MajorDescription, 0, 1);                

    if (strcasecmp($letter, $l) == 0) { 

也许你可以通过将两个块放在一起来优化你的脚本吗?