Heim > Backend-Entwicklung > PHP-Tutorial > Frei von Guzzle5 mit PHP-HTTP und HTTPLUG

Frei von Guzzle5 mit PHP-HTTP und HTTPLUG

Jennifer Aniston
Freigeben: 2025-02-16 10:04:15
Original
290 Leute haben es durchsucht

Frei von Guzzle5 mit PHP-HTTP und HTTPLUG

Key Takeaways

  • httplug, ein Projekt von PHP-HTTP, ermöglicht eine einfache Injektion eines jeden HTTP-Clients in ein SDK, das eine Lösung für Anwendungen bereitstellt, die bereits über einen bevorzugten HTTP-Client verfügen und die Verwendung von Guzzel vermeiden möchten.
  • .
  • Das HTTPLUG-Schnittstellenpaket und das Guzzle 6 können mit dem Komponisten mit dem Befehl PHP-HTTP/Guzzle6-Adapter zusammengezogen werden. Dies ermöglicht die Verwendung von Guzzle 6 oder einem anderen Adapter, der die HTTPClient -Schnittstelle von HTTPLUG implementiert.
  • Das PHP-HTTP-Projekt zielt darauf ab, alle HTTP-Clients in PHP maximal zu unterstützen, einschließlich Guzzle 5 und 6 sowie Zend1 und 2., dies ermöglicht keine Konflikte mit installierten Client-Versionen und einfachem Einstecken des entsprechenden Adapters.
  • Der Diffbot SDK wurde psr-7 kompatibel und empfänglich für andere Implementierungen von HTTP-Clients. Es braucht nur einen Adapter, der die HTTPLUG -Schnittstelle respektiert, damit alles über die Box funktioniert.
  • httplug bietet einen neuen Ansatz zur Abstraxing von HTTP -Client -Implementierungen in Apps und bietet Erweiterbarkeit für die Kosten einer zusätzlichen Abstraktionsebene.

Dieser Artikel wurde von Márk Sági-Kazár und David Buchmann geprüft. Vielen Dank an alle Peer -Rezensenten von SitePoint, die SitePoint -Inhalte so gut wie möglich gemacht haben!


In einer früheren Serie haben wir einen PHP -Client für Diffbot erstellt. Der Kunde arbeitet gut und nutzt relativ weit verbreitet - wir haben sie sogar in einer Live -App getestet, um sicherzustellen, dass es auf NACH ist - aber es hängt stark von Guzzle 5 ab.

Es gibt zwei Probleme damit:

  1. Guzzle 6 ist aus und unterstützt PSR 7. Während der Autor von Guzzle behauptet, Guzzle 5 wird auf absehbare Zeit unterstützt, ist es sicherer, seine Langlebigkeit skeptisch gegenüber zu sein. Außerdem ist es, während PSR 7 seine Macken hat, gut, PSRS zu folgen, wenn auch nur für die Kompatibilität mit anderen Projekten
  2. Jemand, der unseren Kunden in seiner App implementiert, hat möglicherweise bereits einen bevorzugten HTTP -Client in Gebrauch und möchte seine als ihre Verwendung verwenden. Wir sollten eine einfache Injektion von in unserem SDK HTTP -Client in unserem SDK ermöglichen.

zufällig gibt es ein neues Projekt, das es uns ermöglicht, genau das zu tun: httplug.

Frei von Guzzle5 mit PHP-HTTP und HTTPLUG

Hinweis: Sie müssen mit der internen Logik des Diffbot -SDK nicht vertraut sein, um mitzumachen. Der Prozess in diesem Artikel gilt für jedes Paket mit einer konkreten HTTP -Client -Implementierung und ist leicht zu befolgen.

php-http und httplug

php-http ist eine GitHub-Organisation für HTTP-verwandte Tools in PHP. Es bietet HTTPLUG, eine Sammlung von Schnittstellen und Ausnahmen, um einen minimalen HTTP-Client-Vertrag auf der PSR-7-Anfrage und -antwort zu definieren. Implementierungen dieses Vertrags Bereitstellen das virtuelle Paket PHP-HTTP/Client-Implementation.

Dies bedeutet, dass jemand, der Guzzle 6 verwendet, einen PHP-HTTP/Guzzle6-Adapter benötigt, um den Adapter, das HTTPLUG-Schnittstellenpaket und das Guzzle 6 selbst als Abhängigkeit des Adapters zu ziehen.

.

httplug ist der Einstiegspunkt für ein wiederverwendbares Paket. Es ist die Client -Abstraktion, auf der alle Clients (wie der Guzzle6 -Adapter) basieren. Diese Kunden nutzen dann ihre zugrunde liegenden Pakete / Abhängigkeiten weiter - in diesem Fall Guzzle 6.

unten nach oben:
  • Ein HTTP -Client existiert (Guzzle 6)
  • Ein Guzzle 6 -Adapter wird mit Httplug als Schnittstelle dafür erstellt. Wickelt Guzzle 6
  • Eine App, die in der Lage sein muss, HTTP -Anrufe zu tätigen, erfordert eine HTTPLUG -HTTPCLIENT -Schnittstelle und nicht guzzle 6 direkt
  • Die App kann dann Guzzle 6 oder einen anderen Adapter verwenden, der die HTTPClient -Schnittstelle von HTTPLUG implementiert und ein weiteres HTTP -Client von Drittanbietern einwickelt

Der Plan des Teams besteht darin, alle verschiedenen HTTP -Clients in PHP Land maximal zu unterstützen: Guzzle 6, Guzzle 5, Zend2, Zend1 usw. Auf diese Weise hat ein Benutzer eines Frameworks oder einer App keine Konflikte mit installierten Konflikten Client -Versionen und schließen einfach den entsprechenden Adapter in den Mix an.

Beachten Sie, dass wir die Begriffe Adapter und Client

hier fast austauschbar verwenden - die auf HTTPLUG basierenden Adapter sind beide. Sie sind Wrapper für bestehende Kunden, aber direkt als Kunden selbst verwendet.

Unser Plan in diesem Beitrag ist es, die Betonguzzle 5 Abhängigkeit des PHP -Clients von Diffbot durch die HTTPLUG -Version zu ersetzen.

Hinweis: HTTPLUG- und Verwandte Pakete sind Alpha -Software und können als solche geändert werden. Es ist ein riskantes Unterfangen, etwas zu konvertieren, um sie zu verwenden.

Bootstrapping

Wie üblich wird empfohlen, dass wir das Gehöft verbessert haben, um unsere Umgebung zu starten. Sobald wir fertig sind, können wir die aktuelle stabile Version des SDK klonen und testen:
git clone https://github.com/swader/diffbot-php-client
cd diffbot-php-client 
git checkout tags/0.4.5 
composer install
phpunit
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Der letzte Befehl geht davon aus, dass Phpunit weltweit in der Entwicklungsumgebung installiert ist.

Alle Tests sollten bestehen (mit Ausnahme eines übersprungenen, der aufgrund einiger Unsinn fehlerhaft und unfixierbar ist), daher sind wir bereit, mit dem Umbau zu beginnen.

Erste Schritte

Erstens müssen wir eine neue Zweigstelle erstellen, um dieses Upgrade zu entwickeln.

git checkout -b feature-httplug
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Dann fügen wir zwei Abhängigkeiten in unsere Composer.json -Datei hinzu:

git clone https://github.com/swader/diffbot-php-client
cd diffbot-php-client 
git checkout tags/0.4.5 
composer install
phpunit
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Was dies tut, ist, dem Client zu sagen, dass es von nun an von einem virtuellen Paket - diesem eine abhängt. Dies bedeutet, dass die Anwendung mit unserem Diffbot -Client (wie dieser) eine Implementierung dieses Pakets auswählen muss (eines der am Link auf Packagisten aufgeführten Paket). Während der Entwicklung des Pakets wäre es natürlich unmöglich zu testen und zu prüfen, ob alles ohne tatsächliche Implementierung funktioniert. Daher geben wir eine zusätzliche Abhängigkeit von Request-Dev an. Im obigen Fall verwenden wir "php-http/guzzle6-adapter": "~0.2@dev". Wir haben diese bestimmte Version ausgewählt, nur weil sie die neueste ist und es keine stabile Veröffentlichung gibt.

Hinweis: Sie fragen sich vielleicht, warum wir den Ansatz des Hinzufügens von Werten in Composer.json verwendet haben, anstatt Abhängigkeiten im Terminal interaktiv zu deklarieren, wie wir es normalerweise tun. Dies liegt daran, dass ein Komponist für ein virtuelles Paket einen Fehler macht - das Paket gibt es nicht wirklich, es ist nur sein virtueller Name, ein Platzhalter, sodass der Komponist verwirrt ist, ohne zu wissen, was zu installieren ist. Es gibt ein Problem, das eine Änderung dazu hindert, aber es wird wahrscheinlich nicht bald geschehen.

Da die PHP-HTTP-Pakete immer noch unter starker Entwicklung stehen, sollten wir unseren Composer.json-Datei die folgenden zwei Werte hinzufügen:

git checkout -b feature-httplug
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Dies soll die Installation von Entwicklerpaketen (nicht stabil) ermöglichen, bevorzugt jedoch stabile Versionen, wenn sie existieren. Anstatt beispielsweise Phpunit 5.2.x zu holen, wird es 5.0,8 (am aktuellsten zum Zeitpunkt des Schreibens) abrufen, aber es wird auch erfolgreich sein, wenn wir es nach Paketen fragen, die nicht haben stabile Veröffentlichungen (wie der Guzzle6-Adapter).

Wir müssen auch die Abhängigkeit von Guzzle5 entfernen, wenn wir beabsichtigen, Guzzle6 zu installieren. Die Finale erfordern Blöcke wie folgt:

	"require": {
        ...
        "php-http/client-implementation": "^1.0"
    },
    "require-dev": {
        ...
        "php-http/guzzle6-adapter": "~0.2@dev"
    },
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Der Plan

Die Art und Weise, wie das SDK derzeit funktioniert, lautet wie folgt: In der Hauptdiffbot -Klasse setzen wir optional einen HTTPClient. Dies ist derzeit an die Implementierung von Guzzle in Version 5 gebunden. Wenn keine benutzerdefinierte Client -Instanz festgelegt ist, verwendet die Diffbot -Klasse automatisch einen Standard -Client.

Dieser Client wird dann von der Anrufmethode des API Abstract verwendet, um eine GET -Anforderung an die angegebene URL auszustellen. Darüber hinaus gibt es in der Crawl -API -Klasse und der Such -API -Klasse eine benutzerdefinierte Anrufmethode.

Das Ergebnis des Anrufs wird als $ Antwort gespeichert, bei der es sich um eine Guzzle5 -Antwort handelt. Diese Antwort wird dann zusätzlich von der Entitätsfabrik verarbeitet, die ihre Gültigkeit überprüft und Entitäten darstellt, wodurch sie in die Entität -Iterator drückt.

Der Plan ist also:

  1. Ersetzen Sie Diffbot :: Sethttpclient durch eine Methode, bei der eine HTTPLUG -Implementierung akzeptiert
  2. Ändern Sie die Anrufmethoden der API -Abstract, CRABS und Suchklasse, damit sie eine GET -Anforderung mit jeder HTTP -Client -Implementierung ausstellen können, die ihnen zur Verfügung gestellt wird.
  3. Ändern Sie die Entitätsfabrik- und Entität-Iterator, so dass sie nicht mehr von der Guzzle5-Version der Antwort abhängen, sondern das PSR-7-Gegenstück.

Das PHP-HTTP-Projekt verfügt über ein zusätzliches Paket, Utils, das httpMethodsclient enthält. Diese Klasse wickelt eine Nachrichtenfabrik und den HTTP-Client in ein Ganzes ein und erleichtert das Senden von Anfragen mit häufig verwendeten Verben wie GET, Post usw.-somit in etwas Ähnliches übersetzt, was wir bisher hatten: $ client-> get (. ..). Darüber hinaus gibt es auch das PSR-7-ResponseInterface zurück, was bedeutet, dass die Getbody-Methode uns zur Verfügung steht-das bleibt nur die Tojson-Methode unimplementiert, was wir leicht selbst tun können.

Darüber hinaus verfügt das Projekt über eine Erkennungskomponente, die einige statische Klassen zum Aufdecken installierter Fabriken und Clients enthält. Dadurch können wir unserem Endbenutzer in einigen Fällen eine Erfahrung mit einer Nullkonfiguration bieten (siehe DOCs).

Mit dem Schlachtplan können wir mit dem Refactoring beginnen.

Voraussetzungen

Erfordern wir die zusätzlichen Pakete:

git clone https://github.com/swader/diffbot-php-client
cd diffbot-php-client 
git checkout tags/0.4.5 
composer install
phpunit
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Diffbot -Klasse

Die Diffbot -Klasse hat diese Zeile oben:

git checkout -b feature-httplug
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

wir können es einfach ändern in:

	"require": {
        ...
        "php-http/client-implementation": "^1.0"
    },
    "require-dev": {
        ...
        "php-http/guzzle6-adapter": "~0.2@dev"
    },
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Die Sethttpclient -Methode sollte jetzt in der IDE aufflammen und sagen, dass einige erforderliche Parameter fehlen, nämlich der Client zu verwenden, und die Nachrichtenfabrik, mit der Anforderungsinstanzen erstellt werden können.

Die Methode sollte in:

neu gestaltet werden
"prefer-stable": true,
"minimum-stability": "dev"
Nach dem Login kopieren
Nach dem Login kopieren

Alternativ können die Erkennungsklassen mit Verwendung von Anweisungen oben in der Klasse importiert werden.

Diese Änderung hat dem Endbenutzer des Diffbot -SDK nun einen beiden ermöglicht:

  • Lassen Sie ihren eigenen Client installieren und lassen Sie die Erkennungskomponenten zusammen mit httpMethodsclient automatisch um die Dinge kümmern, oder
  • Konfigurieren Sie ihre eigene httpMethodsclient -Instanz, indem Sie eine benutzerdefinierte Instanz eines PSR 7 -Clients und einer Nachrichtenfabrik in eine neue Instanz davon injizieren und in die Sethttpclient -Methode für die volle Flexibilität injizieren
  • injizieren

Die meisten Benutzer verwenden dies für Autopilot.

API Abstract, Crawl und Suche

Als nächstes die Anrufmethoden.

Frei von Guzzle5 mit PHP-HTTP und HTTPLUG

Da die von uns zuvor implementierte HTTPMethodsClient -Instanz eine GET -Methode hat, sind diesbezüglich keine Änderungen erforderlich. Die $ Response -Instanz zeigt jedoch eine MistMatch und aus gutem Grund. Die ursprüngliche $ -Antwort, die vom EntityFactory erwartet wird, ist eine Guzzle5 -Antwort.

Aufgrund der Beschwerde von EntityFactory müssen wir die API -Zusammenfassung nicht wirklich bearbeiten - sie wird sich selbst um die Dinge kümmern. Das Crawl -Class -Call -Gegenstück ist etwas anders:

git clone https://github.com/swader/diffbot-php-client
cd diffbot-php-client 
git checkout tags/0.4.5 
composer install
phpunit
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Zwei Warnungen hier - die zweite Zeile der Methode, die die JSON -Methode von $ response verwendet, und die EntityIterator -Instanziierung, die eine Guzzle5 -Antwort erwartet. Die einzige Linie, die wir von hier aus beeinflussen können, ist die erstere. Wechseln wir sie also in:

git checkout -b feature-httplug
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Eine ähnliche Änderung muss in der Anrufmethode der Suchklasse durchgeführt werden, wobei die Zeile:

	"require": {
        ...
        "php-http/client-implementation": "^1.0"
    },
    "require-dev": {
        ...
        "php-http/guzzle6-adapter": "~0.2@dev"
    },
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

ändert sich in:

"prefer-stable": true,
"minimum-stability": "dev"
Nach dem Login kopieren
Nach dem Login kopieren

Entity Factory

Die EntityFactory -Klasse hat den folgenden Import oben:

    "require": {
        "php" : ">=5.4.0",
        "php-http/client-implementation": "^1.0"
    },
    "require-dev": {
        "symfony/var-dumper": "~2",
        "phpunit/phpunit": "^5.0",
        "php-http/guzzle6-adapter": "~0.2@dev"
    },
Nach dem Login kopieren

wir können dies ändern in:

composer require "php-http/utils" "php-http/discovery"
Nach dem Login kopieren

Das Gleiche muss in der EntityFactory -Schnittstelle erfolgen, die die Entitätsfaktorik impliziert.

Die andere Änderung ähnelt dem, was wir oben in der Crawl -Klasse getan haben. Wir ändern:

use GuzzleHttp\Client;
Nach dem Login kopieren

bis

use Http\Client\Utils\HttpMethodsClient as Client;
Nach dem Login kopieren

in checkResponseformat- und CreateAppropotIderator -Methoden.

Entität Iterator

Wir ändern:

<span>/**
</span><span> * Sets the client to be used for querying the API endpoints
</span><span> *
</span><span> * <span>@param Client $client
</span></span><span> * <span>@see http://php-http.readthedocs.org/en/latest/utils/#httpmethodsclient
</span></span><span> * <span>@return $this
</span></span><span> */
</span><span>public function setHttpClient(Client $client = null)
</span><span>{
</span>    <span>if ($client === null) {
</span>		<span>$client = new Client(
</span>		   <span><span>\Http\Discovery\HttpClientDiscovery</span>::find(),
</span>		   <span><span>\Http\Discovery\MessageFactoryDiscovery</span>::find()
</span>		<span>);
</span>    <span>}
</span>    <span>$this->client = $client;
</span>    <span>return $this;
</span><span>}
</span>
Nach dem Login kopieren

bis

<span>public function call()
</span><span>{
</span>    <span>$response = $this->diffbot->getHttpClient()->get($this->buildUrl());
</span>
    <span>$array = $response->json();
</span>
    <span>if (isset($array['jobs'])) {
</span>        <span>$jobs = [];
</span>        <span>foreach ($array['jobs'] as $job) {
</span>            <span>$jobs[] = new JobCrawl($job);
</span>        <span>}
</span>
        <span>return new EntityIterator($jobs, $response);
</span>    <span>} elseif (!isset($array['jobs']) && isset($array['response'])) {
</span>        <span>return $array['response'];
</span>    <span>} else {
</span>        <span>throw new DiffbotException('It appears something went wrong.');
</span>    <span>}
</span><span>}
</span>
Nach dem Login kopieren

Tests

Verspottung, die Hauptmethode zum Testen von HTTP -Anforderungen und API -Aufrufen ist in Guzzle 6 unterschiedlich, daher erfordern unsere Tests eine etwas größere Überholung.

Da dieses Tutorial auf der langen Seite bereits ein wenig ist .

Schließlich führen wir die Tests durch:

$array = json_decode($response->getBody(), true);
Nach dem Login kopieren

Erfolg! Alle bestehen (mit Ausnahme des erwarteten übersprungenen Tests).

Der Diffbot SDK ist jetzt nicht nur PSR-7-kompatibel, sondern auch für andere Implementierungen von HTTP-Clients empfänglich. Alles, was es braucht, ist ein Adapter, das die HTTPLUG -Schnittstelle respektiert, und alles sollte nicht über die Box gelangen.

Schlussfolgerung

httplug ist ein nützlicher neuer Ansatz zur Abstraxung der HTTP -Client -Implementierungen in den von uns erstellten Apps. Unabhängig davon

Wenn Sie helfen möchten, indem Sie weitere Adapter -Implementierungen hinzufügen oder nur die Pakete ausprobieren und Feedback geben, begrüßt das Team alle Beiträge. Machen Sie sich mit uns in Verbindung oder lassen Sie Ihr Feedback im Kommentarbereich unten. Wenn Sie dieses Tutorial interessant fanden, vergessen Sie nicht, diese Taste wie Schaltfläche zu klicken!

häufig gestellte Fragen (FAQs) zu PHP HTTP und HTTPLUG

Was ist der Unterschied zwischen Guzzle5 und PHP HTTP/HTTPLUG? Guzzle5 ist ein spezifischer HTTP -Client, während PHP HTTP eine Abstraktionsschicht ist, mit der Sie einen HTTP -Client verwenden können. HTTPLUG ist eine Erweiterung von PHP HTTP, die zusätzliche Funktionen bietet. Der Hauptunterschied besteht > Die Migration von Guzzle5 zu PHP HTTP/HTTPLUG beinhaltet den Ersatz des Guzzle5 -Clients durch einen Adapter, der die PHP -HTTP -Schnittstellen implementiert. Dies kann mit der HTTPLUG -Bibliothek erfolgen, die Adapter für verschiedene HTTP -Clients, einschließlich Guzzle5, bereitstellt. Sobald der Adapter eingerichtet ist, können Sie die PHP -HTTP -Methoden verwenden, um Anforderungen zu senden und Antworten zu behandeln. Die Verwendung von PHP HTTP/HTTPLUG über Guzzle5 ist die erhöhte Flexibilität und Interoperabilität. Mit PHP HTTP/HTTPLUG können Sie zwischen verschiedenen HTTP -Clients wechseln, ohne Ihren Code zu ändern. Dies erleichtert es, Ihre Anwendung mit verschiedenen Kunden zu testen und bei Bedarf die Kunden zu wechseln. Zusätzlich bietet HTTPLUG ein Plugin -System, mit dem Sie Ihrem HTTP -Client Funktionen hinzufügen können. Abhängigkeitsmanagement -Tool für PHP. Sie können es installieren, indem Sie den Befehlskomponisten ausführen, der PHP-HTTP/HTTPLUG benötigt. Dadurch wird die HTTPLUG -Bibliothek und ihre Abhängigkeiten heruntergeladen. ein Anforderungsobjekt. Dies kann unter Verwendung der Createrequest -Methode der MessageFactory -Schnittstelle erfolgen. Sobald Sie ein Anforderungsobjekt haben, können Sie es mit der SendRequest -Methode der HTTPClient -Schnittstelle senden. dargestellt durch die ResponseInterface -Schnittstelle. Sie können auf den Statuscode, die Header und den Körper der Reaktion mit dem GetStatuscode, Getheaders bzw. Getbody -Methoden zugreifen. 🎜> Die Erkennungskomponente in PHP HTTP/HTTPLUG wird verwendet, um verfügbare HTTP -Adapter und Nachrichtenfabriken automatisch zu finden und zu verwenden. Dies erleichtert es, zwischen verschiedenen HTTP -Clients zu wechseln und die beste verfügbare Implementierung zu verwenden. Aufrufen der statischen Fundmethode in den HTTPClientDiscovery- oder MessageFactoryDiscovery -Klassen. Dadurch wird eine Instanz des ersten verfügbaren HTTP -Clients oder Nachrichtenfabriks zurückgegeben.

Was sind die Plugins in httplug und wie verwende ich sie? Sie können verwendet werden, um Funktionen wie Authentifizierung, Caching und Fehlerbehandlung hinzuzufügen. Plugins können dem Client unter Verwendung der Adcdplugin -Methode der PluginClient -Klasse hinzugefügt werden. Implementieren Sie die HTTPClientException -Schnittstelle. Sie können diese Ausnahmen fangen und nach Bedarf umgehen. Darüber hinaus können Sie das Fehlerplugin verwenden, um nicht 200 Antworten in Ausnahmen zu konvertieren.

Das obige ist der detaillierte Inhalt vonFrei von Guzzle5 mit PHP-HTTP und HTTPLUG. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage