Strona 1 z 2
Pytanie o skrypt php
: 23 lis 2022, 17:25
autor: huberthx
Witam jak w temacie.
Z PHP mam styczność jakiś czas i nie mam się kogo zapytać czy moje poczynania idą w dobrym kierunku.
Jest to zaczątek sklepu internetowego.
Jest to plik index.php który tak na prawdę łączy wszystko w całość i decyduje o wyświetleniu elementów strony.
Kod: Zaznacz cały
<?php
//index.php
session_start();
define("SCIEZKA","sklep/");
require_once(SCIEZKA . 'Naglowek.php');
require_once(SCIEZKA . 'Menu.php');
require_once(SCIEZKA . 'Infoozalogowaniu.php');
if (isset($_GET['akcja']) && $_GET['akcja'] == "uzytkownik" && !isset($_SESSION['uzytkownik']))
{
require_once(SCIEZKA . 'Uzytkownik.php');
}
if (isset($_GET['akcja']) && $_GET['akcja'] == "zaloguj")
{
require_once(SCIEZKA . 'Uzytkownik.php');
}
if (isset($_GET['akcja']) && $_GET['akcja'] == "zarejestruj")
{
require_once(SCIEZKA . 'Uzytkownik.php');
}
if (isset($_GET['akcja']) && $_GET['akcja'] == "wyloguj")
{
require_once(SCIEZKA . 'Uzytkownik.php');
}
if (isset($_GET['info']) && $_GET['info'] == "nieudanarejestracja")
{
echo "Nie zarejestrowano. Powód: użytkownik o takich danych już istnieje.";
}
if (isset($_GET['info']) && $_GET['info'] == "zarejestrowano")
{
echo "Zarejestrowano nowego użytkownika";
}
if (isset($_GET['akcja']) && $_GET['akcja'] == "pokazprodukty")
{
require_once(SCIEZKA . 'Sklep.php');
}
require_once (SCIEZKA . 'Stopka.php');
?>
W jakim kierunku zmierzam ?
Dziękuję za każda radę.
Re: Pytanie o skrypt php
: 25 lis 2022, 10:18
autor: mario_7
Jest to jakieś wyjście - raczej takie toporne...
Kilka uwag:
- wciąż powtarzasz "isset($_GET['coś']) && $_GET['coś']" - aż się prosi aby z tego funkcję zrobić, co będzie zwracała dane pole z $_GET jeśli tam istnieje.
- sprawdzasz różne wartości dla tego samego pola i potem dołączasz tę samą stronę - to w ramach jednego warunku if można zrobić.
- ify nie są wykluczające się, wiec jak zrobię index.php?akcja=wyloguj&info=zarejestrowano to się załaduje Uzytkownik.php i wyświetli komunikat "Zarejestrowano nowego użytkownika".
Takie warunkowe wciąganie plików sugeruje, że pewnie w nich masz jakiś kod HTML na żywca ze wstawkami PHP - to podejście, które szybko się mści, bo o ile na początku łatwo coś wyświetlić, to potem trudno się to utrzymuje.
O wiele lepszym podejściem byłoby utworzenie obiektów, które generują kod HTML i w zależności od argumentów tworzysz odpowiedni obiekt, który pokazuje stronę taką lub inną.
Ogólnie najlepiej jest maksymalnie rozdzielać warstwę logiki od warstwy prezentacji.
Popatrz w internecie jak to się robi w różnych popularnych projektach - tam stopień skomplikowania będzie trochę duży, ale pewnie znajdziesz też jakieś proste przykłady.
Re: Pytanie o skrypt php
: 25 lis 2022, 11:33
autor: huberthx
Dziękuję za zainteresowanie tematem.
Odnośnie uwag:
Zrobiłem plik Getsprawdzenie.php który wygląda tak:
Kod: Zaznacz cały
<?php
namespace sklep\Getsprawdzenie;
class Getsprawdzenie
{
public function Sprawdz($nazwaget, $wartosc)
{
if (isset($_GET[$nazwaget]) && $_GET[$nazwaget] == $wartosc)
return true;
else
return false;
}
}
Teraz w if-ach wywołuje funkcję Sprawdz z parametrem nazwy get-a i wartością do sprawdzenia
Odnośnie drugiej uwagi:
Nie ująłem wszystkiego co się da w jednym if-ie dla przejrzystości kodu.
Odnośnie trzeciej uwagi:
Rzeczywiście if-y się nie wykluczają i to jest do małej poprawki
Re: Pytanie o skrypt php
: 25 lis 2022, 14:19
autor: mario_7
Ogólna uwaga - jeśli jakiś kod się powtarza, to zazwyczaj można to napisać lepiej - to tak odnośnie tej "przejrzystości kodu".
Re: Pytanie o skrypt php
: 25 lis 2022, 16:01
autor: huberthx
Kolejne pytanie:
Oto kod i pytanie: jeśli robię coś źle to co robię źle ?
Skrypt ten jest dołączany do pliku index.php.
Dodam że działa prawidłowo.
Oto kod:
Kod: Zaznacz cały
<?php
namespace Sklep;
require_once 'Bazadanych.php';
use sklep\Bazadanych\Bazadanych;
require_once('Getsprawdzenie.php');
use sklep\Getsprawdzenie\Getsprawdzenie;
class Sklep
{
//odczytuje produkty z bazy danych
private function Pokazprodukty()
{
$polaczenie = new Bazadanych();
$polaczenie = $polaczenie->Polaczzbaza();
$Wynik = $polaczenie->query("SELECT * FROM produkty");
$polaczenie->close();
return $Wynik;
}
//odczytuje produkty z koszyka z bazy danych
private function Pokazkoszyk()
{
if (isset($_SESSION['iduzytkownik'])):
$iduzytkownik = $_SESSION['iduzytkownik'];
$polaczenie = new Bazadanych();
$polaczenie = $polaczenie->Polaczzbaza();
$Wynik = $polaczenie->query("SELECT * FROM koszyk, produkty WHERE koszyk.iduzytkownika = $iduzytkownik AND koszyk.idproduktu = produkty.id");
$polaczenie->close();
endif;
return $Wynik;
}
//dodaje produkt do koszyka (czyli do odpowiedniej tabeli bazy)
public function Dodajdokoszyka($idproduktu)
{
$iduzytkownik = $_SESSION['iduzytkownik'];
$polaczenie = new Bazadanych();
$polaczenie = $polaczenie->Polaczzbaza();
$polaczenie->query("INSERT INTO koszyk (iduzytkownika,idproduktu) VALUES ($iduzytkownik,$idproduktu)");
$polaczenie->close();
//tworzę liczbę określającą ilość elementów w koszyku którą potem odczytuje z sesji
if (isset($_SESSION['iloscwkoszyku']))
$_SESSION['iloscwkoszyku'] = $_SESSION['iloscwkoszyku'] + 1;
else
$_SESSION['iloscwkoszyku'] = 1;
}
//pokazuje liste produktów do kupienia
public function Listaproduktow()
{
$Wynik = $this->Pokazprodukty();
echo "<div class='row'><div class='col-md-12'>";
echo "<table class='table'>";
echo "<col style='width: 50%'>";
echo "<col style='width: 30%'>";
echo "<col style='width: 20%'>";
foreach ($Wynik as $Wiersz)
{
echo "<tr>
<td>". $Wiersz['marka'] ."</td>
<td>". $Wiersz['cena'] ."</td><td>";
if (isset($_SESSION['uzytkownik']))
{
$id = $Wiersz['id'];
/*
* kliknięcie poniższego elementu uruchamia kod javascript (jquery) korzystający z ajaxa
* oto ten kod
* <script type='text/javascript'>
* $(document).ready(function(){
* dodajdokoszyka = $('span.idproduktu');
* dodajdokoszyka.click(function(){
* idproduktu = $(this).attr('class').split(" ")[1];
* $.ajax(
* {
* url: 'index.php',
* method: 'post',
* dataType: 'text',
* data: { dodajdokoszyka: true , idproduktu: idproduktu},
* }).done(function(){
* //niestety poniższej funkcji najchętniej bym nie użył ale tylko wtedy informacja o
* //ilości produktów odświerza mi się i wyświetla prawidłowo - PYTANIE: CO ROBIĘ ŹLE ??
* location.reload(true);
* });
* });
* });
* </script>
*/
echo "<span class='idproduktu $id'>Dodaj do koszyka</span>";
}
echo "</td></tr>";
}
echo "</table>";
echo "</div></div>";
}
//pokazuje liste produktów w koszyku
public function Listaprodoktowwkoszyku()
{
$cenasuma = 0;
$Produktywkoszyku = $this->Pokazkoszyk();
echo "<div class='row'><div class='col-md-12'>";
echo "<table class='table'>";
echo "<col style='width: 60%'>";
echo "<col style='width: 40%'>";
foreach ($Produktywkoszyku as $Produkt)
{
echo "<tr>";
echo "<td>" . $Produkt['marka'] . "</td>";
echo "<td>" . $Produkt['cena'] . "</td>";
echo "</tr>";
$cenasuma += $Produkt['cena'];
}
echo "</table>";
echo "</div></div><div class='row text-center'>";
echo "<div class='col-md-10'>Cena za wszystkie produkty z koszyka wynosi: " . $cenasuma . ".</div>";
echo "<div class='col-md-2'><a href='index.php?akcja=zaplac'>Zapłać</a></div>";
echo "</div></div>";
}
}
$Getsprawdzenie = new Getsprawdzenie();
$Sklep = new Sklep();
//jeżeli trzeba pokazać produkty
if ($Getsprawdzenie->Sprawdz('akcja', 'pokazprodukty'))
{
$Sklep->Listaproduktow();
}
//jeżeli trzeba pokazać zawartosć koszyka
if ($Getsprawdzenie->Sprawdz('akcja', 'pokazproduktywkoszyku') && isset($_SESSION['iduzytkownik']))
{
$Sklep->Listaprodoktowwkoszyku();
}
//jeżeli kliknęliśmy "Dodaj do koszyka
if (isset($_POST['dodajdokoszyka']))
{
$Sklep->Dodajdokoszyka($_POST['idproduktu']);
}
Re: Pytanie o skrypt php
: 25 lis 2022, 19:23
autor: huberthx
Dodałem do swojej klasy nową funkcję do łączenia z bazą danych ponieważ w poprzedniej wersji skryptu kod się powtarzał wielokrotnie.
Kod: Zaznacz cały
private function Zapytajbaze($zapytanie)
{
$polaczenie = new Bazadanych();
$this->polaczenie = $polaczenie->Polaczzbaza();
$Wynik = $this->polaczenie->query($zapytanie);
return $Wynik;
}
Re: Pytanie o skrypt php
: 28 lis 2022, 10:35
autor: mario_7
Ogólna uwaga - kiepsko to wygląda. Czy to w ogóle było zaprojektowane, czy tak jest pisane w miarę potrzeb? Tutaj by się przydał generalny refactoring, bo funkcjonalności mało, a już jest kaszanka...
Odporny na błędy na pewno ten skrypt nie jest - odwoływanie się do elementów tablicy, które mogę nie istnieć, zwracanie zmiennych, które mogą być niezdefiniowane, obsługi błędów w zasadzie brak, niewykluczające się warunki w ifach na końcu, kod JS co robi reload, nazwy metod nieadekwatne do tego co robią, nazwy zmiennych generyczne zamiast opisowych (wynik, wiersz), drukowanie kodu html wewnątrz php (lepiej zastąpić to choćby jakimś prymitywnym systemem szablonów stron)...
Nawiązywanie połączenia z bazą w każdej metodzie albo dla każdego zapytania jest bez sensu - lepiej to zrobić raz - albo w konstruktorze, albo w jakiejś metodzie dla obiektu całego sklepu - potem metody odpowiedzialne za konkretne akcje powinny się odwoływać do jakiegoś pola z połączeniem do bazy danych.
Zdecydowanie polecam przemyśleć architekturę tego rozwiązania - spisać sobie wymagania/potrzeby, przygotować szkic projektu - "rozrysować" sobie z jakich modułów ma się składać, ich relacje - a potem dopiero to zaprogramować.
Re: Pytanie o skrypt php
: 28 lis 2022, 14:56
autor: huberthx
Dziękuję za cenne uwagi.
Zrobiłem przymiarkę do pobierania danych z adresu url.
Oto kod:
Kod: Zaznacz cały
<?php
namespace Konfiguracja\Trasowanie;
class Trasowanie
{
static public function Odczytajadres($parametr) : bool
{
preg_match("/[a-z]+$/", $_SERVER['REQUEST_URI'],$otrzymanadana);
//tu powinno być sprawdzenie czy $otrzymanadana jest tablicą - is_array($otrzymanadana)
if (count($otrzymanadana) == 1)
{
if ($parametr == $otrzymanadana[0])
{
return true;
}
else
{
return false;
}
}
else
if (count($otrzymanadana) != 1)
{
return false;
}
}
}
?>
Czy ta przymiarka jest dobra czy powinienem coś zmienić ?
Mówiąc 'dobra' chodzi mi o to czy właśnie w ten sposób wyciąga się dane z adresu url ?
Jaka jest różnica w wydajności jeśli chodzi o wywoływanie metod statycznych a zwykłych ?
Re: Pytanie o skrypt php
: 29 lis 2022, 09:20
autor: mario_7
Chcesz robić coś, co robi $_GET, $_POST czy też $_REQUEST?
Tak, czy siak - rzuć okiem na parse_url() i parse_str().
Re: Pytanie o skrypt php
: 29 lis 2022, 11:47
autor: huberthx
Moja struktura katalogów wygląda teraz tak:
Kod: Zaznacz cały
- Konfiguracja
- Sklep:
- Kontrolery
- Modele
- Widoki
index.php
W jaki sposób przekazywać dane między kontrolerem a widokiem ?
Czy sesje to złe rozwiązanie (bo wydaje mi się że złe) ?
Re: Pytanie o skrypt php
: 30 lis 2022, 15:00
autor: huberthx
Problem z sesjami się rozwiązał. Wystarczyło użyć zmiennej $GLOBALS.
Re: Pytanie o skrypt php
: 01 gru 2022, 14:12
autor: mario_7
W większości przypadków korzystanie ze zmiennych globalnych oznacza, że kod mógłby być napisany lepiej, aby tego uniknąć.
Re: Pytanie o skrypt php
: 01 gru 2022, 20:55
autor: huberthx
Mój kontroler wygląda tak:
Kod: Zaznacz cały
<?php
namespace Moduly\Sklep\Kontrolery\sklep;
require_once 'Moduly/Sklep/Modele/sklep.php';
use Moduly\Sklep\Modele\sklep\sklep as sklepmodel;
require_once 'Konfiguracja/wywolajwidok.php';
use Konfiguracja\wywolajwidok\wywolajwidok;
class sklep
{
public function pokazprodukty()
{
$sklep = new sklepmodel();
$produktyzbazy = $sklep->pobierzproduktyzbazy();
if ($produktyzbazy)
{
wywolajwidok::wywolajwidok("Sklep","pokazprodukty",$produktyzbazy);
}
else
{
wywolajwidok::wywolajwidok("Sklep","pokazprodukty",'brakproduktow');
}
}
}
try {
$sklep = new sklep();
$akcja = $GLOBALS['akcjakontrolera'];
$sklep->$akcja();
} catch (\Exception $e) { echo $e->getLine(); };
Nie jest to żadna finalna wersja więc mogą być niedociągnięcia. Niestety użyłem zmiennej globalnej bo na prawdę nie przychodzi mi do głowy jak ją zastąpić.
Wstawiam kod aby ktoś mi doradził jak poprzednio czy idę w dobrym kierunku ?
Przepraszam że tak ciągnę ten temat ale nie mam się kogo zapytać, jestem samoukiem i nie chce rozwijać się w kierunku który jest zły stąd prośba o opinie.
Re: Pytanie o skrypt php
: 05 gru 2022, 16:16
autor: mario_7
Tak ogólnie - straszny ten kod. Mało co jest zrobione "zgodnie ze sztuką" - czyli tak, aby działało dobrze i jednocześnie nadawało się do rozbudowy/utrzymania.
Ta zmienna globalna i sposób jej użycia - to taka wisienka na torcie - nie rób tak. To z pewnością da się napisać lepiej... Mam nadzieję, że ta akcjakontrolera nie pochodzi z jakiegoś POST albo GET bo to już będzie potencjalnie luka bezpieczeństwa...
Zacznij od przerobienia jakichś kursów, nawet darmowych, przejrzyj jakieś sensowne projekty open source, podejrzyj jak się tam różne rzeczy robi, potem usiądź i zastanów się co chcesz zrobić, zaprojektuj to (forma dowolna - rysunek, opis, tabelka... pomyśl jakie będziesz miał obiekty, jak się będą wołały, jakie API potrzebujesz) i dopiero zacznij pisać. Jeśli chcesz być samoukiem - spoko - ale rób to z głową. Wiedzy w internecie jest mnóstwo - wystarczy z niej skorzystać. Bez sensu zaczynać jest od przyswajania sobie złych praktyk - zacznij od poznania tych dobrych i stosowania ich od samego początku.
Re: Pytanie o skrypt php
: 05 gru 2022, 20:24
autor: huberthx
Rozpocząłem pisanie nowego przykładowego kodu.
Nie używam teraz zmiennych globalnych do przekazania nazwy metody kontrolera (akcji). Użyłem do tego singletonu.
Kod: Zaznacz cały
<?php
//to plik odpowiedzialny za konfigurację routingu (chyba tak to się po angielsku nazywa)
require_once "src/routes.php";
use src\routes\routes;
$routes = new routes();
//poniżej pierwszy parametr to pierwsza część adresu a drugi to druga część adresu czyli w przeglądarce musze wpisać adres/index.php/stronaglowna
$routes->dodajadres("stronaglowna","","StronaGlownaController","indexAction");
I drugi plik który chciałem pokazać:
Kod: Zaznacz cały
<?php
//to jest ten mój nieszczęsny kontroler
namespace app\controllers\StronaGlownaController;
require_once "src/przekazywanieakcji.php";
use src\przekazywanieakcji\akcje;
class StronaGlownaController
{
public function __construct()
{
$akcja = akcje::getInstance();
if ($akcja != null)
$this->$akcja();
else
return false;
}
public function indexAction()
{
//wiem tego tu nie powinno być
echo "WYWOŁANO";
}
}
$StronaGlownaController = new StronaGlownaController();
Re: Pytanie o skrypt php
: 06 gru 2022, 11:58
autor: mario_7
Nie poddajesz się - to dobrze, ale dalej brniesz w fatalnym kierunku - to źle...
To wciąż bardzo nieudany kod jest...
Co niby to akcje::getInstance() zwraca? Jeśli to singleton, to powinno zwrócić instancję tego singletona, a jednak tutaj to zwraca nazwę funkcji do zawołania... Czyli to raczej nie jest singleton...
Jaką masz gwarancję, że jeśli akcja nie jest nullem, to taka funkcja istnieje w ogóle? Wołasz ją dosyć beztrosko.
Dlaczego konstruktor zwraca jakąś wartość? Teoretycznie można tak zrobić, ale nie znam dobrego powodu, aby to robić... Jak korzystasz z tej zwracanej wartości?
Mieszasz polskie i angielskie nazwy - zaciemnianie kodu.
Powtórzę jeszcze raz - zacznij od podstaw, zapoznaj się z dobrymi praktykami programowania, przemyśl co chcesz zrobić i dopiero zabierz się za pisanie...
Re: Pytanie o skrypt php
: 06 gru 2022, 13:39
autor: huberthx
Czy mógłbyś podać jakiś dobry kurs w internecie o robieniu własnego frameworka php mvc ?
Może jakąś książkę albo kurs do kupienia ?
Będę bardzo wdzięczny i dziękuję za Twoje zaangażowanie mario_7.
Re: Pytanie o skrypt php
: 06 gru 2022, 16:41
autor: mario_7
PHP to nie moja bajka - wiele lat temu trochę się nim interesowałem, ale obecnie nie mam w zasadzie z nim styczności (poza doraźnymi poprawkami w wordpressie czy phpbb tutaj na forum

).
Zacząłbym od standardowych miejsc - czyli po prostu strona domowa PHP, potem udemy (są darmowe kursy), linkedin learning (darmowy miesiąc powinien wystarczyć na obejrzenia ciekawych kursów), youtube (tutaj warto pewnie znaleźć jakieś kursy polecane przez renomowane portale, bo pewnie sporo różnej jakości porad też się znajdzie). Zapewne więcej dowiesz się zaglądając na jakieś tematyczne forum czy inną społeczność skupioną wokół tego języka.
Re: Pytanie o skrypt php
: 06 gru 2022, 18:49
autor: huberthx
Wkleiłem tu wcześniej kod który miał rażące błędy dlatego usunąłem. Przepraszam
Re: Pytanie o skrypt php
: 07 gru 2022, 17:38
autor: huberthx
Wrzucę jeszcze jeden fragment kodu z prośbą o opinie:
Kod: Zaznacz cały
<?php
class trasowanie
{
const TRASADOKONTROLERA = "aplikacja/kontrolery/";
//przekazujemy końcówkę adresu url, nazwę klasy kontorlera i jego metode (akcję)
//na przykład: $trasowanie->trasowanie('produktysklep/pokazprodukty','ProduktyKontroler','akcjaPokaz');
public function trasowanie($adresdostrony, $kontroler, $metoda) : bool
{
$adres = $_SERVER['REQUEST_URI'];
$wprowadzonyadres = explode("/", $adres);
$wprowadzonyadrespoodwroceniukolejnosci = array_reverse($wprowadzonyadres);
$adresdostrony = explode("/", $adresdostrony);
$adresdostronypoodwroceniukolejnosci = array_reverse($adresdostrony);
if ($wprowadzonyadrespoodwroceniukolejnosci[0] == $adresdostronypoodwroceniukolejnosci[0]
&& $wprowadzonyadrespoodwroceniukolejnosci[1] == $adresdostronypoodwroceniukolejnosci[1])
{
require_once self::TRASADOKONTROLERA . $kontroler . ".php";
if (class_exists($kontroler))
{
$kontroler = new $kontroler();
$kontroler->$metoda();
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
}
?>
Kod odpowiada za wywołanie kontrolera i akcji
Jeszcze się dokształcam o spl_autoload_register