problem z przekazaniem zmiennej z kontrolera

Odpowiedz Nowy wątek
2019-06-08 14:20
0

Cześć,
Mam taki problem w projekcie, pojawia się błąd niezdefiniowanej zmiennej - slowa w pliku losuj.php
Dlaczego jak odpalę podstronę losuj.php ręcznie poprzez adres ( https://localhost/pai/?page=losuj) to wszystko działa natomiast jeśli dołączę tą podstronę za pomocą funkcji include do index to wywala błąd niezdefiniowanej zmiennej :(
Gorąca prośba o pomoc.

index.php

<!DOCTYPE html>
<html>

<?php include(dirname(__DIR__).'/head.html'); ?>

<body>
<?php include(dirname(__DIR__).'/navbar.html'); ?>

<div class="container bg">
        <br><br><br>
        <div class="row">
            <div class="col-md-12 offset-md-3" style="margin: auto; background: white; padding: 20px; box-shadow: 10px 10px 5px #888">
                <div class="panel-heading">
                    <h2>Nauka słówek</h2>
                    <p style="font-style: italic;">Słowo: <?php include("views/SlowoController/losuj.php") ?></p>
                </div>
                <hr>

                <form action="?page=camera" method="POST">
                    <button type="submit" style="border-radius: 0px;" class="btn btn-lg btn-block btn-outline-success">Zrób zdjęcie</button>
                </form>

            </div>
        </div>
    </div>

</body>
</html>

losuj.php


<!DOCTYPE html>
<html>
<?php include(dirname(__DIR__).'/head.html'); ?>
<body>
<div class="container">
    <div class="row">
        <h4 class="mt-4">Slowo:</h4>
        <table class="table table-hover">
            <thead>
            <tr>
                <th> <?php foreach ($slowa as $slowo) {
                echo "<tr><td>{$slowo['slowo']}</td></tr>";
                }
            ?>

        </th>
            </tr>
            </thead>

        </table>
    </div>
</div>

</body>
</html>

Slowo.php

<?php
require_once __DIR__.'/../Database.php';

class Slowo{
    private $s;

    public function __construct($s){
        $this->s = $s;
    }

    public function getSlowo(){
        return $this->s;
    }

    public function setSlowo($s): void{
        $this->s = $s;
    }  
}

SlowpMapper.php

<?php

require_once 'Slowo.php';
require_once __DIR__.'/../Database.php';

class SlowoMapper{ 
    private $database;

    public function __construct(){
        $this->database = new Database();
    }

    public function getSlowa(){
        try {
            $stmt = $this->database->connect()->prepare('SELECT slowo FROM slowa WHERE id_slowo = 2');
            $stmt->execute();
            $slowo = $stmt->fetchAll(PDO::FETCH_ASSOC);
            return $slowo;
        }
        catch(PDOException $e) {
            die();
        }
    }
}

SlowoController.php



```<?php

require_once "AppController.php";
require_once __DIR__.'/../model/Slowo.php';
require_once __DIR__.'/../model/SlowoMapper.php';

class SlowoController extends AppController{
    public function __construct(){
        parent::__construct();
    }

    public function SlowoLst(){
        $mapper = new SlowoMapper();

            $slowo = $mapper ->getSlowa();
            $this->render('losuj', ['slowa' => $slowo]);
    }
}
edytowany 2x, ostatnio: marnit, 2019-06-08 16:27

Pozostało 580 znaków

2019-06-08 19:26
0

Cześć,

Jeśli dobrze zrozumiałem, mówisz o natywnej funkcji include()? Chcąc jej użyć w ten sposób, musisz wcześniej zadeklarować zmienną $slowa. Być może gdzieś przed wywołaniem tej funkcji, żeby pozostawić losuj.php z minimalną ilością logiki. Funkcja include niejako wkleja kod z pliku w miejscu jej wywołania.

Jeśli ładujesz widok metodą render(), ta przekazuje zmienną $slowa jako parametr.


Software Developer, PHP, MySQL, JS
edytowany 3x, ostatnio: Lukasz Formela, 2019-06-08 19:27
Pokaż pozostałe 3 komentarze
Okej, ale teraz musisz też ręcznie te słowo z bazy pobrać, spróbuj $words = $words->getSlowa(). W ten sposób przypisujesz wynik zapytania do bazy do zmiennej $words, co powinno rozwiązać problem przy ręcznym ładowaniu pliku. Jeśli jednak nie jest to wymagane w Twoim projekcie, pozostań przy ładowaniu widoku z adresu. EDIT: Może lepiej byłoby użyć tu innej zmiennej, jak $slowa = $words->getSlowa(); żeby nie nadpsywać zmiennej z obiektem. - Lukasz Formela 2019-06-08 20:59
ok, tylko teraz pojawia się kolejny problem. Słowo (losowe), które odczytuje z bazy wyświetlam w dwóch różnych plikach (podstronach). Jak zrobić tak by na każdej podstronie było to samo słówko, obecnie na każdej mam inne, bo tworze nowy obiekt i słówko losuje się na nowo. - marnit 2019-06-09 14:00
Myślałem, ze rozwiążę to za pomocą klasy Slowo więc za pomocą setSlowo zapisałem słowo w zmiennej $Slowo (w klasie Slowo), jednak gdy chcę odczytać tą zmienną z innego pliku (podstrony) to ta zmienna jest pusta, nie ma w niej zapisanego żadnego słowa - marnit 2019-06-09 14:57
Aj, grubsza sprawa :) Czy strona "losuj.php" ma być w ogóle odpalana poza kontrolerem? W tym momencie masz całą logikę gotową. Uruchamianie pojedyńczych stron pomija kontroler. Drugie pytanie, to czemu jest to losowe słowo jeśli zapytanie robisz dla konkretnego ID? Powinno z każdego obiektu zwrócić to samo. Możesz podawać do zapytania do bazy jakiś parametr zamiast gotowego "id_slowo", wtedy obojętnie skąd zaczniesz, pobierzesz ten sam rekord. - Lukasz Formela 2019-06-09 15:11
Wcześniej chciałem losować liczbę z danego przedziału, i potem tą liczbę przekazywać do zapytania i wyświetlać konkretne słowo z tym id, ale musiałbym wcześniej policzyć liczbę słów w tabeli. Uznałem, że lepszym rozwiązaniem będzie modyfikacja zapytania. Obecnie moje zapytanie do bazy wygląda tak: SELECT word FROM words ORDER BY RAND() LIMIT 1. Zaraz wrzucę plik losuj.php - marnit 2019-06-09 15:18

Pozostało 580 znaków

2019-06-09 15:19
0

Chcę osiągnąć taki efekt, by słowo, które zostanie wylosowane będę mógł wyświetlić na innej podstronie. Obecnie jest tak, ze na każdej losuje się od nowa :(

losuj.php

<!DOCTYPE html>
<html>
<?php include(dirname(__DIR__).'/head.html'); ?>
<body>
<?php include(dirname(__DIR__).'/navbar.html'); ?>
<div class="container">
    <div class="row">
        <table class="table table-hover">
            <thead>
            <tr>
                <th>Wylosowane słówko: </th>     
            <?php 
                foreach ($words as $slowo) {
                echo "<tr><td>{$slowo['word']}</td></tr>";
                }

           ?>
            </tr> 
            </thead>
        </table>

    </div>
</div>
</body>
</html>
edytowany 2x, ostatnio: marnit, 2019-06-09 15:26

Pozostało 580 znaków

2019-06-09 15:43
0

No to jak chcesz przekazywać słowo między stronami, to użyj cookies albo sesji.

A nie ma innego prostszego sposobu? - marnit 2019-06-09 15:47

Pozostało 580 znaków

2019-06-09 19:53
0

Przecież to jest proste... Jeśli chcesz zapamiętać wartość jakiejś zmiennej, to musisz ją zapisać w czymś, co umożliwia utrwalenie jej bez utraty po odświeżeniu strony. Są jeszcze 2 opcje:

1) Zapis do bazy - ale to trochę przerost formy nad treścią
2) Zapis w urlu jako parametr GET - tylko to brzydkie rozwiązanie i dużo łatwiej użyć cookies/sesji

Pozostało 580 znaków

2019-06-09 20:01
0

Zabrałem się za to i niby wszystko ok, ale nie do końca. Przy pierwszym uruchomieniu przeglądarki wyrzuca błąd niewłaściwego indeksu slowko. Po odświeżeniu strony wszystko jest ok.

setcookie('slowko', $slowo['word']);
echo "cookie: ", $_COOKIE['slowko'];

Zacząłem to jakoś zabezpieczać, ale nie bardzo mi to wychodzi.Zrobiłem więc tak, ale nic to nie dało :(

foreach ($words as $slowo) {
                echo "<tr><td>{$slowo['word']}</td></tr>";

                if (isset($COOKIE['slowko'])) {

                    echo "cookie: ", $_COOKIE['slowko'];
                } else{
                    setcookie('slowko', $slowo['word']);
                    echo "cookie: ", $_COOKIE['slowko'];

                }
            }
edytowany 2x, ostatnio: marnit, 2019-06-09 20:25
Pokaż pozostałe 2 komentarze
Hmm, no tak, skoro kolega tak uważa to możesz zostawić cookies ;) - Markuz 2019-06-09 20:27
:) tylko coś mi nie działa, nie za bardzo wiem gdzie mam błąd, że przy pierwszym uruchomieniu strony wywala błąd, a po odświeżeniu wszystko jest ok. Wg. mnie powyższy kod powinien to zabezpieczyć, niestety jest inaczej :( - marnit 2019-06-09 20:30
Mógłbyś pokazać nam treść tego błędu? - Markuz 2019-06-09 20:45
Masz literówkę, nie $COOKIE tylko $_COOKIE - to może być przyczyną - Markuz 2019-06-09 20:46
niestety to nie to :( zaraz wrzucę całą treść błędu - marnit 2019-06-09 21:06

Pozostało 580 znaków

2019-06-09 21:10
0

treść błędu:

screenshot-20190609210931.png

losuj.php

<!DOCTYPE html>
<html>
<?php include(dirname(__DIR__).'/head.html'); ?>
<body>
<?php include(dirname(__DIR__).'/navbar.html'); ?>
<div class="container">
    <div class="row">
        <table class="table table-hover">
            <thead>
            <tr>
                <th>Wylosowane słówko: </th>     
            <?php 
                foreach ($words as $slowo) {
               # echo "<tr><td>{$slowo['word']}</td></tr>";

                if (isset($_COOKIE['slowko'])) {

                    echo "cookie: ", $_COOKIE['slowko'];
                } else{
                    setcookie('slowko', $slowo['word']);
                    echo "cookie: ", $_COOKIE['slowko'];

                }
            }

            ?>
            </tr> 
            </thead>
        </table>

    </div>
</div>
</body>
</html>

Pozostało 580 znaków

2019-06-09 21:14

Pierwsze zdanie z docs: https://www.php.net/manual/en/function.setcookie.php

setcookie() defines a cookie to be sent along with the rest of the HTTP headers

Czyli jak użyjesz funkcji setcookie, to dane zostaną wysłane w nagłówkach żądania i trafią do PHP dopiero przy kolejnym żądaniu. Zmień sobie ten kod tak aby robił setcookie i wyświetlał poniżej dane z $slowo['word'] a nie z $_COOKIE.

edytowany 2x, ostatnio: Markuz, 2019-06-09 21:15
no, ale jak tak zrobie to na innej podstronie będę miał inne słówko, a chce mieć to samo - marnit 2019-06-09 21:16
a dobra, chyba wiem o co chodzi :) - marnit 2019-06-09 21:29

Pozostało 580 znaków

2019-06-09 21:27
1
<?php

$words = ['cow', 'cat', 'dog'];

if (isset($_COOKIE['word'])) {
    echo $_COOKIE['word'];
} else {
    $word = $words[array_rand($words)];
    setcookie('word', $word);
    echo $word;
}

Cookies jest dzielone pomiędzy plikami (w ramach tej samej domeny), więc nie powinno Ci losować słówka od nowa. Spróbuj sobie skopiować powyższy skrypt do 2 plików i sprawić żeby się wyświetliły 2 różne słowa (nie powinno się to udać). Twój kod można zmniejszyć objętościowo, dlaczego robisz te wszystkie klasy Slowo, Controller, Mapper? Twój kod jest strukturalny, zapisałeś go jednak w klasach przez co masz więcej kodu i jest jeszcze bardziej skomplikowany.

edytowany 2x, ostatnio: Markuz, 2019-06-09 21:30

Pozostało 580 znaków

2019-06-09 21:33
0
Markuz napisał(a):
<?php

$words = ['cow', 'cat', 'dog'];

if (isset($_COOKIE['word'])) {
    echo $_COOKIE['word'];
} else {
    $word = $words[array_rand($words)];
    setcookie('word', $word);
    echo $word;
}

Cookies jest dzielone pomiędzy plikami (w ramach tej samej domeny), więc nie powinno Ci losować słówka od nowa. Spróbuj sobie skopiować powyższy skrypt do 2 plików i sprawić żeby się wyświetliły 2 różne słowa (nie powinno się to udać). Twój kod można zmniejszyć objętościowo, dlaczego robisz te wszystkie klasy Slowo, Controller, Mapper? Twój kod jest strukturalny, zapisałeś go jednak w klasach przez co masz więcej kodu i jest jeszcze bardziej skomplikowany.

Z Twojej wcześniejszej odpowiedzi, zrozumiałem, żebym zrobił tak:

  foreach ($words as $slowo) {
                echo "<tr><td>{$slowo['word']}</td></tr>";
                setcookie('slowko', $slowo['word']);
            }

Jednak po Twoim kolejnym wpisie, chyba nie to miałeś na myśli?

edytowany 1x, ostatnio: marnit, 2019-06-09 21:34
Nie, przeanalizuj mój kod, pomyśl, prześpij się z tym ;) - Markuz 2019-06-09 21:34

Pozostało 580 znaków

2019-06-13 23:20
0

Podpowie mi jeszcze ktoś dlaczego przycisk register nie działa? Nie przekierowuje mnie do innej podstrony, wyrzuca błędy o niezdefiniowanym index name, surname, email z pliku defaultController.php. Sign in działa normalnie. Nie mam już pomysłu co może być nie tak :( Gorąca prośba o pomoc.

login.php

<!DOCTYPE html>
<html>
<body>

<div>
               <form action="?page=login" method="POST">
                <div class="form-group row">
                    <label for="inputEmail" class="col-sm-1 col-form-label">
                        <i class="material-icons md-48">email</i>
                    </label>
                    <div class="col-sm-11">
                        <input type="email" class="form-control" id="inputEmail" name="email" placeholder="email" required/>
                    </div>
                </div>
                <div class="form-group row">
                    <label for="inputPassword" class="col-sm-1 col-form-label">
                        <i class="material-icons md-48">person</i>
                    </label>
                    <div class="col-sm-11">
                        <input type="password" name="password" class="form-control" id="inputPassword" placeholder="password" type="password" required/>
                    </div>
                </div>
                <input type="submit" value="Sign in" class="btn btn-primary btn-lg float-right" />

            </form>
            <form action="?page=register" method="POST">
            <input type="submit" value="Register" class="btn btn-primary btn-lg float-left" />
            </form>
</div>

</body>
</html>

defaultController.php

<?php

require_once "AppController.php";

require_once __DIR__.'/../model/User.php';
require_once __DIR__.'/../model/UserMapper.php';

class DefaultController extends AppController
{

    public function __construct()
    {
        parent::__construct();
    }

      public function login()
    {
        $mapper = new UserMapper();

        $user = null;

        if ($this->isPost()) {

            $user = $mapper->getUser($_POST['email']);

            if(!$user) {
                return $this->render('login', ['message' => ['Email not recognized']]);
            }

            if ($user->getPassword() !== md5($_POST['password'])) {
                return $this->render('login', ['message' => ['Wrong password']]);
            } else {
                $_SESSION["id"] = $user->getEmail();
                $_SESSION["role"] = $user->getRole();

                $url = "https://$_SERVER[HTTP_HOST]/pai";
                header("Location: {$url}?page=index");
                exit();
            }
        }

        $this->render('login');
    }

       public function register()
    {
        $mapper = new UserMapper();
        $user = null;

        if ($this->isPost()) {
            $user = new User(
              $_POST['name'],
              $_POST['surname'],
              $_POST['email'],
              md5($_POST['password'])

            );
            $mapper->setUser($user);

            $this->render('login', [
                'message' => ['You have been successful registrated! Please login.']
                ]);
        }

        $this->render('register');
    }
}

screenshot-20190613232024.png

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0