Autor Zpráva
SkyVessel
Profil
Zdravím,
nevm proč, ale v cyklu for mám uzavřený while. Ten se ale provede jen jednou.
for (;;) {
    $t = mktime (0, 0, 0, $date->month, $date->day++ , $date->year);
    $date_j = date ("j", $t);
##
        while ($aktualni_plan = mysql_fetch_array($vysledek_pom, MYSQL_NUM)) {
//
            if (($aktualni_plan[1] == $date_j) && ($akt_mesic)) {
              $title = "$title \n $aktualni_plan[3]";
              $style_plan = "background-color:#FFFF99;";
            }
        }
    }
While se provede jen jednou, a to na začátku. Proměnná $date_j se normálně načítá tak, jak má, ale to while se provede jen na začátku - když dám echo na $date_j na msto ##, tak mi to krásně vypíše dny tak, jak má. Když dám echo třeba $aktualni_plan[3] na místo //, tak mi to vypíše správně všechny proměnné, ale jen po prvním výpisu data - pak už se neprovede:
31 aktualni_plan: b, aktualni_plan: c, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 1 2 3 4
WertriK
Profil
SkyVessel:
Když dám echo třeba $aktualni_plan[3] na místo //, tak mi to vypíše správně všechny proměnné, ale jen po prvním výpisu data - pak už se neprovede:

Tak je to správně. Zkus napsat co od toho chceš.
peta
Profil
To je kus jakehosi kodu, ktery neni uplny, neda se otestovat ani klonovat bez doplneni veci, ktere muzou obsahovat prave tu chybu. Cili, mi to pojede s celym timto kodem, tobe ne. Co ti mam pak napsat jako odpoved? :) Kdyby se mi teda chtelo ty podstatne casti doplnovat.

1. echo $query
2. zkopirovat query do phpmyadminu a vypise to jeden radek nebo vice? Jeden radek = jedno while.
3. vypis $aktualni_plan se da realizovat i pomoci print_r nebo var_dump
4. $title = "$title \n $aktualni_plan[3]";
To je velice spatny zpusob vkladani promennych do retezce. Lepsi je nahrazovani, treba pres sprintf a nebo spojovani. Je mozne, ze to budes muset doplnit zavorkami
$title = "$title \n {$aktualni_plan[3]}";
5. for (;;) ???
6. mysql_fetch_array -- ja pouzivam radeji mysql_fetch_assoc
7. Ten kod nema zadny vypis, tudiz vypsat nic nemuze, ale pises neco jineho.
8. ($aktualni_plan[1] == $date_j) && ($akt_mesic) -- ktera cast podminky selze?
echo ($aktualni_plan[1] == $date_j)*1; echo ($akt_mesic)*1;

Takze bych doporucil udelat si php soubor bokem, ktery obsahuje jen tu malou cast, kterou chces, na otestovani, pak to funkcni vlozit do programu. tak mas jistotu, ktera cast kodu jede a ktera ne a nebudes sem davat kod, ktery se jevi ok.
Joker
Profil
SkyVessel:
Jestli dotaz do databáze není uvnitř for-cyklu, pochopitelně ten while v prvním běhu for-cyklu projede všechny výsledky a v dalších cyklech se už neprovede (protože už žádné další řádky nebudou).

Nejspíš jsou špatně navržené ty cykly (jestli součástí toho for není dotaz do databáze, skoro určitě jsou špatně navržené ty cykly).

peta:
ad 1.: Žádná proměnná $query v ukázce není
ad 5.: !!!
ad 6.: S mysql_fetch_assoc mu to přestane fungovat. Jinak samozřejmě mysql rozšíření jako celek by se už nemělo používat.
ad 7.: Vždyť popisuje, kam dává výpis
ad 8.: Problém bude spíš s podmínkou ve while.
SkyVessel
Profil
OK, vkládám sem podstatnou část kodu. Asi jsem se vyjádřil nedostatečně: v poli $aktualni_plan mám uložené hodnoty typu: uživatel, den, měsíc, směna. cyklus for() mi vytváří tabulku s jednotlivými buňkami kalendáře. Já potřebuji, aby se mi pokaždé projela proměnná $aktualni_plan a pokud daný den existuje směna, aby se pozadí políčka kalendáře obarvilo jinak a ještě se doplnil titulek.
Výpis z KONTROLNÍCH proměnných je 31 akt_plan: b dne 31. akt_plan: c dne 31. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 1 2 3 4
V tabulce mám opravdu jen dvě směny (b, c), ale jde mi o to, že cyklus while() se provede jen jednou a to hned při prvním procházení cyklu for(). Jelikož je ale první směna až dvacátého a druhá 27., tak se pole neobarví. Mě napadlo, že se ta proměnná v tom cyklu while() nějak vyprázdní a pak už to nechce vzít, tak ji zkouším před každým cyklem znovu naplnit.

<?php
require_once ('mysql_spojit.php');

class Ccolor {
    var $wday_txt = "#bbbbdd";
    var $wend_txt = "#ddbbbb";
    var $wday = "#000000";#"#ccccee";
    var $wend = "#000000";#"#eecccc";
    var $wday_noact = "#999999";#"#9090a6";
    var $wend_noact = "#a69090";
    var $today = "#ff0000";#"#ffffc0";
    var $bgwday = "#ffffff";
    var $bgwend = "#dddddd";
    }
    
$color = new Ccolor ();

class Cdate {
    var $day;
    var $month;
    var $year;

    function Cdate ($time) {
        $this->day = date ("j", $time);
        $this->month = date ("n", $time);
        $this->year = date ("Y", $time);
        }
    }

$date = isset ( $time ) ? new Cdate ( $time ) : new Cdate ( time () );
$m = array (1 => "Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Záží", "Říjen", "Listopad", "Prosinec");
$d = array ("Po", "Út", "St", "Čt", "Pá", "So", "Ne");

echo "<table border='0' cellspacing='1' cellpadding='0' class='kalendar'>\n";
echo "<tr align='center' valign='middle'><td colspan='7'><b> ".$m[$date->month]." $date->year </b></td></tr>\n"; 
echo "<tr align='center' valign='middle'>\n";
for ($i=0 ; $i<count($d) ; $i++) {
    $bgcolor = ($i < 5) ? $color->wday_txt : $color->wend_txt;
    echo "<td bgcolor='$bgcolor' class='cell'><b>".$d[$i]."</b></td>\n";
    }
echo "</tr>\n";

$date->day = 1 - date ("w", mktime (0, 0, 0, $date->month, 0, $date->year));

# - - - - - - -  cyklus - - - - - - - -

$act_month_end = false;
$aktualni_mesic = date ("n", $time);
$dotaz = "SELECT * FROM smena_user WHERE user = '$user[0]' AND mesic_smeny = '$aktualni_mesic'";
$vysledek = mysql_query($dotaz) or die(mysql_error());

for (;;) {

    $t = mktime (0, 0, 0, $date->month, $date->day++ , $date->year);
    $date_n = date ("n", $t);
    $date_w = date ("w", $t);
    $date_j = date ("j", $t);

    if ($date_n == $date->month)
        $act_month_end = true;

    // první pondělí v dalším měsíci ukončí cyklus
    if ($act_month_end == true && $date_n != $date->month && $date_w == 1) {
        echo "</tr>";
        break;
        }
    // pondělí na nový řádek
    else if ($date_w == 1)
        echo "<tr align='center'>\n";

    // předchozí nebo následující měsíc
    if ($date_n != $date->month) {
        $bgcolor = ($date_w==0 || $date_w==6) ? $color->wend_noact : $color->wday_noact;    # $bgcolor
        $bcgcolor = ($date_w==0 || $date_w==6) ? $color->bgwend : $color->bgwday;
        $akt_mesic = false;
    }

    // aktuální měsíc
    else {
        $bgcolor = ($date_w==0 || $date_w==6) ? $color->wend : $color->wday;
        $bcgcolor = ($date_w==0 || $date_w==6) ? $color->bgwend : $color->bgwday;
        $akt_mesic = true;
    }

    if (date("dmY",$t) == date("dmY"))
        $bgcolor = $color->today;

    $title = date ("j.n. Y", $t);

    $style_plan = ""; //  jiná barva, pokud je směna
    $vysledek_pom = $vysledek;  //opětovné načtení dotazu
    echo "$date_j ";  // KONTROLNÍ výpis dne
    
    # - - - - - - kontrola naplánovaných směn - - - - - -
    
        while ($aktualni_plan = mysql_fetch_array($vysledek_pom, MYSQL_NUM)) {
echo " akt_plan: $aktualni_plan[3] dne $date_j. "; //  KONTROLNÍ výpis směny
            if (($aktualni_plan[1] == $date_j) && ($akt_mesic)) {  // den v daném měsíci
              $title = "$title \n $aktualni_plan[3]";   //  přidat směnu do hintu
              $style_plan = "background-color:#FFFF99;";
            }
        }

    echo "<td title='$title' style='color:$bgcolor; background-color:$bcgcolor; $style_plan' class='cell'>".date ("d", $t)."</td>\n";
    }
    
?>

peta
V phpadminu se vypše dobře. I na webu, ale potřebuji, aby se ten while opakoval celou dobu cyklu for. A to for(;;) není z mojí hlavy, ale funguje dobře. Je to špatně?
Joker
Profil
SkyVessel:
Na řádku 52 je opravdu for (;;) {?
Deklarovat nekonečný cyklus a někam dovnitř dát logiku, která vyskočí ven, považuji za prasárnu.

Dále uvozovky se píší jen kolem řetězců, ne při výpisu proměnné.

Problém bude v ř. 91:
    $vysledek_pom = $vysledek;  //opětovné načtení dotazu
„Opětovné načtení dotazu“- říká kdo? Nic takového to neudělá, vlastně je to úplně zbytečná operace, výsledek by byl úplně stejný kdyby tam proměnná $vysledek_pom nebyla a místo ní se používalo $vysledek.

Problém je přesně v tom, co jsem říkal:
V prvním běhu cyklu for se provede cyklus while a spotřebuje všechny vybrané záznamy z databáze. Tím pádem ve druhém a dalším běhu cyklu for se cyklus while už neprovede, protože žádné další řádky už nejsou (všechny spotřeboval ten první běh).

Komentář na ř. 91 nemá pravdu, datový typ resource je jen ukazatel na nějaký externí zdroj, čili jeho zkopírování do jiné proměnné udělá jen kopii toho ukazatele, ne kopii celého toho zdroje.
SkyVessel
Profil
Joker:
Takže jsem to vyřešil. Potřeboval jsem nakopnout správným směrem... Ten problém, jak jsi ho popisoval, jsem předpokládal, tak jsem ho zkusil odstranit právě tím $vysledek_pom. Teď už vím, že to nepojede :).

před for() jsem dal
$dotaz = "SELECT * FROM smena_user WHERE user = '$user[0]' AND mesic_smeny = '$aktualni_mesic'";
$vysledek = mysql_query($dotaz) or die(mysql_error());

while ($zaznam = mysql_fetch_array($vysledek)) {
  $aktualni_plan[] = $zaznam;
}
a to nefunkční while jsem nahradil fci foreach() v cyklu for()

    
    foreach ($aktualni_plan as $dny) {
        if (($dny[1] == $date_j) && ($akt_mesic)) {
            $title = "$title \n $dny[3]";
          $style_plan = "background-color:#FFFF99;";
        }
     }

Takhle mi to už funguje... No, ještě v tom plavu :).

K tomu řádku 52: opravdu to tak je a breakuji to v cyklu. Jak to vyřešit jinak, když dopředu neznám přesný počet opakování? Jinak já to tak našel v jednom vzorovém příkladu =)
peta
Profil
49, 50 bys musel dat dovnitr for cyklu. Lepsi je ulozit si to do pole predem, jak jsi to udelal.

Prvni pondeli se da zjistit snadno. Zjistis 1.1. ktery je den $N = date('N',$t) a 1+8-$N je cislo dne, ne?
1 pondeli, 7 nedele
$N vyjde treba 3, streda. 1+8-3 = 6, cili 6.1.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: