NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: mimo array

V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Vojtěch Janoušek:20.11.2018 0:34

Ahoj, potreboval bych poradit s metodou vyjezd() ve tride Parkoviste. Jsme tam mimo pole a nevim proc. Dostavam: Notice: Undefined offset: 2 in C:\xampp\htdoc­s\Parking\tri­dy\Parkoviste­.php on line 48

Fatal error: Uncaught Error: Call to a member function getSpz() on null in C:\xampp\htdoc­s\Parking\tri­dy\Parkoviste­.php:48 Stack trace: #0 C:\xampp\htdoc­s\Parking\tri­dy\Auto.php(22): Parkoviste->vyjezd(Objec­t(Auto)) #1 C:\xampp\htdoc­s\Parking\index­.php(39): Auto->odjezd(Objec­t(Parkoviste)) #2 {main} thrown in C:\xampp\htdoc­s\Parking\tri­dy\Parkoviste­.php on line 48

Diky z pomoc

Zkusil jsem:

<?php
require 'tridy/Auto.php';
require 'tridy/Parkovis­te.php';
$parkoviste = new Parkoviste(5);

$auto1 = new Auto('ADT-25-68', 'červená');
$auto2 = new Auto('KOE-52-31', 'zelená');
$auto3 = new Auto('JNA-36-55', 'bílá');
$auto4 = new Auto('BAN-11-73', 'modrá');
$auto5 = new Auto('ZAZ-32-92', 'žlutá');
$auto6 = new Auto('RUR-74-54', 'černá');
$auto7 = new Auto('LOL-23-52', 'hnědá');

$auto1->vjedNaParkovis­te($parkoviste);
$auto2->vjedNaParkovis­te($parkoviste);
$auto3->vjedNaParkovis­te($parkoviste);
$auto4->vjedNaParkovis­te($parkoviste);
$auto5->vjedNaParkovis­te($parkoviste);
$auto6->vjedNaParkovis­te($parkoviste);
$auto7->vjedNaParkovis­te($parkoviste);

$parkoviste->vypisAuta();
echo 'nevesla se </br>';
$parkoviste->neveslaSe();
echo '</br>';
$auto3->odjezd($parko­viste);
$auto4->odjezd($parko­viste);
$parkoviste->vypisAuta();
?>

<?php

class Auto{

private $spz;
private $barva;

public function __construct($spz, $barva) {
$this->spz = $spz;
$this->barva = $barva;
}

public function getSpz(){
return $this->spz;
}

public function vjedNaParkovis­te($parkoviste) {
$parkoviste->vjezd($this);
}

public function odjezd($parkoviste) {
$parkoviste->vyjezd($this);
}

}

<?php

class Parkoviste{

private $kapacitaParko­viste;
private $obsazenost=0;
private $parkoviste = array();
private $bufferAut = array();

public function __construct($ka­pacita) {
$this->kapacitaParkoviste = $kapacita;
}

private function jeVolno(){
if($this->kapacitaParkoviste > $this->obsazenost){
return true;
} else{
return false;
}
}

public function vjezd($auto){
if(Parkoviste::je­Volno()){
$this->parkoviste[] = $auto;
$this->obsazenost++;
} else{
$this->bufferAut[] = $auto;
}
}

public function vypisAuta() {
$i=0;
foreach ($this->parkoviste as $p) {
echo $i . ' ' . $p->getSpz() . '<br/>';
$i++;
}
}

public function neveslaSe(){
foreach ($this->bufferAut as $a) {
echo $a->getSpz() . '<br/>';
}
}

public function vyjezd($auto){
//echo count($this->parkoviste) . '<br/>';
for($i=0; $i<count($this->parkoviste);$i++){
if($auto->getSpz() == $this->parkoviste[$i]->getSpz()){
echo $i . '<br/>';
unset($this->parkoviste[$i]);
}
}
}

}

Chci docílit: Cilem je cviceni.

Editováno 20.11.2018 0:35
 
Odpovědět
20.11.2018 0:34
Avatar
Odpovídá na Vojtěch Janoušek
Martin Konečný (pavelco1998):20.11.2018 2:36

Ahoj, zkus ten kód uvést do značky "Vložit zdrojový kód" (nad textarea hned druhá ikonka), pak ti někdo dokáže poradit.

Je drobnost ohledně návrhu - mezi třídou Autor a Parkoviste může být obousměrná 1:N vazba. Tedy Auto může mít objekt $parkoviste jako atribut a v momentě zavolání $auto->vjedNaParkovis­te($parkoviste) se objekt k autu uloží. Tím uchováš stav auta, že je aktuálně na parkovišti. Při výjezdu pak není nikde potřeba předávat objekt $parkoviste, protože auto v jednu chvíli může (logicky) být jen na jednom parkovišti, a jelikož si jeho instanci uchovává v sobě, ví, od kterého parkoviště má odjet :D

Editováno 20.11.2018 2:37
Nahoru Odpovědět
20.11.2018 2:36
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:20.11.2018 8:05

https://www.tutorialspoint.com/…ormatter.htm + tlacitko code </>

<?php
require 'tridy/Auto.php';
require 'tridy/Parkoviste.php';
$parkoviste = new Parkoviste(5);
$auto1 = new Auto('ADT-25-68', 'červená');
$auto2 = new Auto('KOE-52-31', 'zelená');
$auto3 = new Auto('JNA-36-55', 'bílá');
$auto4 = new Auto('BAN-11-73', 'modrá');
$auto5 = new Auto('ZAZ-32-92', 'žlutá');
$auto6 = new Auto('RUR-74-54', 'černá');
$auto7 = new Auto('LOL-23-52', 'hnědá');
$auto1->vjedNaParkoviste($parkoviste);
$auto2->vjedNaParkoviste($parkoviste);
$auto3->vjedNaParkoviste($parkoviste);
$auto4->vjedNaParkoviste($parkoviste);
$auto5->vjedNaParkoviste($parkoviste);
$auto6->vjedNaParkoviste($parkoviste);
$auto7->vjedNaParkoviste($parkoviste);
$parkoviste->vypisAuta();
echo 'nevesla se ';
$parkoviste->neveslaSe();
echo '';
$auto3->odjezd($parkoviste);
$auto4->odjezd($parkoviste);
$parkoviste->vypisAuta();
?>

<?php
class Auto {
    private $spz;
    private $barva;
    public function __construct($spz, $barva) {
        $this->spz = $spz;
        $this->barva = $barva;
    }
    public function getSpz() {
        return $this->spz;
    }
    public function vjedNaParkoviste($parkoviste) {
        $parkoviste->vjezd($this);
    }
    public function odjezd($parkoviste) {
        $parkoviste->vyjezd($this);
    }
} < ? phpclass Parkoviste {
    private $kapacitaParkoviste;
    private $obsazenost = 0;
    private $parkoviste = array();
    private $bufferAut = array();
    public function __construct($kapacita) {
        $this->kapacitaParkoviste = $kapacita;
    }
    private function jeVolno() {
        if ($this->kapacitaParkoviste > $this->obsazenost) {
            return true;
        } else {
            return false;
        }
    }
    public function vjezd($auto) {
        if (Parkoviste::jeVolno()) {
            $this->parkoviste[] = $auto;
            $this->obsazenost++;
        } else {
            $this->bufferAut[] = $auto;
        }
    }
    public function vypisAuta() {
        $i = 0;
        foreach ($this->parkoviste as $p) {
            echo $i . ' ' . $p->getSpz() . '
';
            $i++;
        }
    }
    public function neveslaSe() {
        foreach ($this->bufferAut as $a) {
            echo $a->getSpz() . '
';
        }
    }
    public function vyjezd($auto) {
        //echo count($this->parkoviste) . '
        ';
for($i=0; $i<count($this->parkoviste);$i++){
if($auto->getSpz() == $this->parkoviste[$i]->getSpz()){
echo $i . '';
unset($this->parkoviste[$i]);
}
}
}

}
 
Nahoru Odpovědět
20.11.2018 8:05
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:20.11.2018 8:12
  1. chyba } < ? phpclass Parkoviste
  2. chyba //echo count($this->parkoviste) . '

    ';

    public function vyjezd($auto) {
        //echo count($this->parkoviste) . '
        //';
        for ($i = 0;$i < count($this->parkoviste);$i++) {
            if ($auto->getSpz() == $this->parkoviste[$i]->getSpz()) {
                echo $i . '
';
                unset($this->parkoviste[$i]);
            }
        }
    }
}

No, a kdyz unsetnes z parkoviste neco, tak se zmeni pocet prvku v array, znovu se prepocita count a nebudou ti sedet indexy.
x = array(1,2,3,4,5)
count(x) = 5
i = 2 -> x[i] = 3
unset(x[i]) // x=array(1,2,4,5)
count(x) = 4
i++ -> i = 3 -> x[i] = 5
Auto 4 jsi uplne vynechal.

A pravdepodobne kvuli tomu ti zlobi i dalsi veci.
Mimochodem, na odradkovani muzes pouzit "\n" nebo '\n'.

Editováno 20.11.2018 8:13
 
Nahoru Odpovědět
20.11.2018 8:12
Avatar
Vojtěch Janoušek:20.11.2018 16:33

Ahoj, díky za typy. Na předání reference do atributu se podívám. Díky. Nicméně jse metodu přepracoval takhle:

public function vyjezd($auto) {
                    if (($key = array_search($auto->getSpz(), $this->parkoviste)) !== false) {
                            unset($this->parkoviste[$key]);
                    }
    }

Ale stejně jsem v koncích...neprojdu přes podmíku. Už mi to nejde do hlavy. Díky za rady. A zdar.

 
Nahoru Odpovědět
20.11.2018 16:33
Avatar
Vojtěch Janoušek:21.11.2018 13:06

Ahoj, dali jsme to s kamosem dohromady. Kdyby to nekoho zajimalo a nebo to nekdy nekomu pomohlo, tak tady:

public function vyjezd($auto){
        foreach($this->parkoviste as $n => $a){
            if($a->getSpz() == $auto->getSpz()){
                unset($this->parkoviste[$n]);
                echo $auto->getSpz() . " odjelo<br>";
                $this->obsazenost--;
                break;
            }
                }
        return $this->parkoviste;
    }

Konstrukci " foreach($this->parkoviste as $n => $a){" jsme neznal a v tom je byl ten hacek. Mozna by stalo doplnit do serialu.

Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět
21.11.2018 13:06
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21.11.2018 14:51

Foreach neni dulezite, ale to, ze pri unsetovani musis postupovat od konce. Ne i++ a i<len ale i-- a i>=0.

 
Nahoru Odpovědět
21.11.2018 14:51
Avatar
Vojtěch Janoušek:21.11.2018 16:40

Diky Petere,
to mi nedoslo. Tak jsem to prepracoval.

public function vyjezd($auto){
                for($i = $this->obsazenost-1; $i>=0; $i--){
                        if($this->parkoviste[$i]->getSpz() == $auto->getSpz()){
                                unset($this->parkoviste[$i]);
                                echo $auto->getSpz() . " odjelo<br>";
                                break;
                        }

                }
                $this->obsazenost;
        }
 
Nahoru Odpovědět
21.11.2018 16:40
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.