Pakiranje PHP "use" unutar funkcije

Pozdrav,

napravio sam instalaciju sa composerom jednog lib-a za konvert html to pdf. (što je u cijeloj priči najmanje bitno)

I sada da bi koristio funkcionalnost konvertiranja html-a u pdf …code izgleda ovako:

	require 'vendor/autoload.php';

	$dompdf = new Dompdf();
	$dompdf->loadHtml("HTML content is here");

	// (Optional) Setup the paper size and orientation
	$dompdf->setPaper('A4', 'portrait');

	// Render the HTML as PDF
	$dompdf->render();


	$output = $dompdf->output();

	file_put_contents('test.pdf', $output);

…i to šljaka. Ono što ja želim, imati svoj modul/funkciju koja se zove html2pdf($html)
Briga me što će biti u tom modulu, hoće li se moj modul oslanjati na ovaj Dompdf lib …ili jednog dana na neki drugi. Hoću samo da moj modul za ulazni $html mi vraća pdf source.

Pošto sada imam ovaj Dompdf lib, logično želim svoj modul napraviti da radi preko njega…nešto ovakvo:

	function html2pdf($html){

		require_once 'vendor/autoload.php';

		// reference the Dompdf namespace
		use Dompdf\Dompdf;

		// instantiate and use the dompdf class
		$dompdf = new Dompdf();
		$dompdf->loadHtml($html);

		// (Optional) Setup the paper size and orientation
		$dompdf->setPaper('A4', 'portrait');

		// Render the HTML as PDF
		$dompdf->render();

		$output = $dompdf->output();

		return $output;

	}

Problem nastaje što syntax “use” ne može biti unutar funkcije. Pa kako bi to trebalo posložiti da šljaka, s obzirom da je instalacija ovog lib-a nastala putem composera?

Hvala. :slight_smile:

The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it cannot be block scoped. The following example will show an illegal use of the use keyword.
https://www.php.net/manual/en/language.namespaces.importing.php#98908

Probaj ovako(ps. kucano je napamet nije testirano):

class html2pdf{
	require_once 'vendor/autoload.php';
	use Dompdf\Dompdf;
	public function convert($html) {
		$dompdf = new Dompdf();
		$dompdf->loadHtml($html);

		// (Optional) Setup the paper size and orientation
		$dompdf->setPaper('A4', 'portrait');

		// Render the HTML as PDF
		$dompdf->render();

		$output = $dompdf->output();

		return $output;
	}
}
1 Like

To se u PHP-u zove interface i u saradnji sa DI-jem odlično ispunjava svrhu.

1 Like

Nece ti ni to funkcionirati jer se Use nalazi unutar klase. Jedan nacin je @tpojka vec napisao i on je onaj koji je pravi.

@bozoou ako ne zelis onako kako ti je @tpojka napisao onda moras use staviti na pocetak file-a, a poslije require.

file.php
<?php

require_once 'vendor/autoload.php';

use Dompdf\Dompdf;
 
function html2pdf($html) {
    $dompdf = new Dompdf();
    ....

ili ako neces tako onda
file.php
<?php

function html2pdf($html) {
    require_once 'vendor/autoload.php';
    $dompdf = new Dompdf/Dompdf();
    ....

I prvi i drugi nacin su validni, drugi nacin i require unutar funkcije nije preporucljiv radi citljivosti samo koda, debugiranja i ovisnosti koje na taj nacin stvaras, da ne govorim o tome da taj vendor/autoload.php nebi trebao uvoziti 300 puta.

Zato danas svi frameworci, popularni, koriste index file gdje uvezu to i pokrenu cijelu aplikaciju. Nesto slicno kao u drugim jezicima i funkcija main().

2 Likeova

To sam bio i probao…pa nije htjelo raditi, iz kojeg god razloga…
A na kraju me iznenadi da radi ovako…

use Dompdf\Dompdf;
function html2pdf($html) {
    require_once 'vendor/autoload.php';
    $dompdf = new Dompdf();
    ....

Svjestan :slight_smile:
Ali zahtjev je da sve bude upakirano unutar html2pdf …i da to bude independent modul. Ako modul zavisi od logike autoloada frameworka, onda to više nije to.

Ionako kasnije najvjerovatnije neće biti unutar modula ovo što je sad… Najbitnije mi je da modul odrađuje ispravno prijenosnu funkciju ulaza na izlaz i da što manje ispravan rad toga zavisi od okolne logike frameworka i ostalih globalnih utjecaja.
Tako kada u nekom noobie projektu trigiram tako neki modul, želim imati što manje okolnih podešavanja da isti proradi. Onda mi je radni flow brži… i održavanje mi se tako pokazalo jednostavnije.

Al proučit ću interface što je linkao @tpojka, pari i meni da interface ispunjava svrhu toga…samo još nije bila sila koristiti ga.

Fala na pomoći. :wink:

Pa tebi Dompdf paket ispunjava zadatak. Savjet je da ne brljaš ovako kako si kren’o već da koristiš paket kako se koristi.
Ako se bojiš da će u budućnosti Dompdf da se izmijeni tol’ko da ti je neupotrebljiv, a ti koristi verziju koja tebi odgovara (trenutnu?)

{
    "name": "jdoe/aw",
    "description": "Awesome Package",
    "type": "metapackage",
    "require": {
        "dompdf/dompdf": "0.8.5"
    },
    "license": "MIT",
    "authors": [
        {
            "name": "John Doe",
            "email": "[email protected]"
        }
    ],
    "autoload": {
        "PSR-4": {
            "Jdoe\\Aw\\": "src/"
        }
    },
    "minimum-stability": "dev"
}

I tako si zaključ’o Dompdf na verziju i ne zanima te nadogradnja paketa. Tebi će sa ovakvim composer.json fajlom uvijek stizati odredjena verzija. Nikakvo prepravljanje funkcija ti nije potrebno.

Zapravo zaebao sam…unatoč zahtjevu require_once 'vendor/autoload.php'; ne pripada unutar modula :slight_smile:

Je l’ se radi o custom aplikaciji?

Googlaj Front controller pattern to ti je pattern s kojim loadaš sve kroz index.php file.

Ne radi se o tome. Nego ako koristiš direktno Dompdf bez wrappera (ili ti ga interface-a) onda se dešavaš da imaš na 101 mjesto u codu pozive prema Dompdf. A kako svaki drugi projekt radi sa PDF-om, onda ti se desi da na svim projektima imaš poziva prema Dompdf-u, tj. ukupno “N x 101” poziva, gdje je N broj projekata.

A Dompdf ne rješava stvar idealno…jer ništa nije idealno. Danas sutra se odlučim na library koji brže (ili preciznije) kreira PDF i što ću? Mjenjati na “N X 101” mjestu Dompdf sa novim libom?

A ovako sam ga fino wrapao, i trebam promijeniti samo ono što je unutar wrapera da se prebacim na novi library, te zadržavam identičnu sintaksu code-a prema svim mojim projektima. (To i jeste smisao riječi “interface”, ako se ne varam …jer sučelje mog library-a onda ostaje identično za pozive iz bilo kojega projekta, pa je zamjena modula praktički bezbolna)

Osim toga, novi library za PDF može doći sa drugačije zamišljenim parametrima, ali to se sve samo premapira unutar wrapera, tako da zadavanje parametra unutar moga code-a ostaje identično…takoreć, ne mora se baš po ničem drndati da se zamjeni Dompdf lib sa nekim naprednijim library-em.

Mislim da si mi ti još davno ukazao na autoloader kako se postavlja…i to koristim od tada. Tako da imam podešene autoloadere na svojim projektima. Ovdje sam malo zabrljao, što nisam uočio da samo trebam svoje autoloadere prilagoditi da prepoznaju ako postoji composerov autoloader i da to tamo podesim.

Jer, malo je preambiciozno očekivati od modula html2pdf da odrađuje baš sve, pa i includanje potrebnih fileova. Jer ionako u nekom mjestu code-a se mora includati file koji sadrži modul html2pdf, a to je onda idealno mjesto gdje će se odraditi i sav ostali include o kojem projekt zavisi.

Tako da priznajem, bilo je glupo taj require trpati unutar modula. :slight_smile:

Ne. Koristeći kapacitet OOP-a samo na jednom mjestu mijenjaš. Na tom linku gore je opisano kako.

Zato i pitam je l’ u pitanju custom aplikacija. Djeluje da jeste i mogu samo predložiti korištenje modernog FW-a (Mezzio, Slim, Symfony, Laravel, Laminas).
Dalje teško da mogu biti od pomoći u trenutnoj strukturi.

Evo što ti je @creatifcode napis’o

Ovo ti je najjednostavniji primjer. I sada u tom fajlu uključiš 'vendor/autoload.php' sve autoload klase/funkcije iz composer.json fajla su dostupne svugdje. Ali opet, to je vrlo bazičan, školski primjer:
FW-ci imaju svu moguću funkcionalnost uvrštenu.

Evo još jedan zanimljiv primjer DI putem interface-a
a ovo je bukvar što se tiče DI-a.

Ostalo neću ni komentarisati jer je koncept totalno pogrešan i svodi se na više špageti koda i grdjeg zapetljavanja.

Pa samo uradi composer require dompdf/dompdf i funkcioniše.
Composer Scheme. <- kako da uključiš funkcije/fajlove da su ti dostupni u projektu.

1 Like

To je sve teska kemija.:sweat_smile::sweat_smile::sweat_smile:

@tpojka
Pogledao sam prvi i zadnji framework sa liste.

U svojem frameworku imam froncontroller, load, router, db, common i to je to. Ne volim komplicirat. Zivot je prekratak.:sweat_smile::sweat_smile::sweat_smile:

Za ostalo imam pluginove.

Npr. problem od @bozoou, bi rijesio kroz plugin.

Framework mi se loada ispod 2 ms, moze se horizontalno skalirat itd…

Ne može samo od sebe. Uči se.

Ovisi, netko ima vremena, netko ne. Netko voli raditi tako, netko ne.:sweat_smile::sweat_smile::sweat_smile:

Kad se u pogrešan voz udje, svaka stanica je pogrešna.

1 Like

Ja sam uskočio na dobar voz i na vrijeme napravio prekretnicu. :smiley: :smiley: :smiley:

Kad se nauči koncept kako treba mijenjanje jezika i tehnologija je stvar rutine.

2 Likeova

Hoces reci ondak nije bitno putujes li vozom ili autobusom :slight_smile: