problem z przekazaniem zmiennej z kontrolera

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]);
    }
}
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.

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>

0

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

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
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'];
            
                }
            }
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>

1

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.

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.

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?

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

0

Masz warningi, bo się odwołujesz do zmiennej, która nie istnieje. Idę o zakład, że chodzi o $_POST[jakis_index]. Tylko że linijki mi się nie zgadzają w warningach (może to z powodu użycia require).

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