
{"id":9823,"date":"2025-05-02T09:07:48","date_gmt":"2025-05-02T02:07:48","guid":{"rendered":"https:\/\/tapchicntt.com\/?p=9823"},"modified":"2025-05-02T09:10:04","modified_gmt":"2025-05-02T02:10:04","slug":"php-huong-dan-tich-hop-gemini-vao-website-php","status":"publish","type":"post","link":"https:\/\/tapchicntt.com\/php-huong-dan-tich-hop-gemini-vao-website-php\/","title":{"rendered":"[PHP] H\u01b0\u1edbng d\u1eabn t\u00edch h\u1ee3p Gemini v\u00e0o website php"},"content":{"rendered":"\n<p>Hi\u1ec7n t\u1ea1i Google ch\u01b0a cung c\u1ea5p m\u1ed9t SDK ch\u00ednh th\u1ee9c d\u00e0nh ri\u00eang cho PHP \u0111\u1ec3 t\u01b0\u01a1ng t\u00e1c tr\u1ef1c ti\u1ebfp v\u1edbi API c\u1ee7a Gemini. Tuy nhi\u00ean, b\u1ea1n v\u1eabn c\u00f3 th\u1ec3 t\u00edch h\u1ee3p b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng c\u00e1c th\u01b0 vi\u1ec7n HTTP client c\u1ee7a PHP \u0111\u1ec3 g\u1eedi c\u00e1c y\u00eau c\u1ea7u API \u0111\u1ebfn c\u00e1c endpoint c\u1ee7a Gemini.<\/p>\n\n\n\n<p>D\u01b0\u1edbi \u0111\u00e2y l\u00e0 h\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1c b\u01b0\u1edbc v\u00e0 v\u00ed d\u1ee5 c\u1ee5 th\u1ec3 \u0111\u1ec3 b\u1ea1n c\u00f3 th\u1ec3 b\u1eaft \u0111\u1ea7u:<\/p>\n\n\n\n<p><strong>B\u01b0\u1edbc 1: Chu\u1ea9n b\u1ecb API Key c\u1ee7a Gemini<\/strong><\/p>\n\n\n\n<p>Tr\u01b0\u1edbc khi b\u1eaft \u0111\u1ea7u, b\u1ea1n c\u1ea7n c\u00f3 API key \u0111\u1ec3 x\u00e1c th\u1ef1c c\u00e1c y\u00eau c\u1ea7u \u0111\u1ebfn API c\u1ee7a Gemini. B\u1ea1n c\u00f3 th\u1ec3 t\u1ea1o API key theo c\u00e1c b\u01b0\u1edbc sau:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Truy c\u1eadp v\u00e0o <a href=\"https:\/\/console.cloud.google.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Google Cloud Console<\/a>.<\/li>\n\n\n\n<li>N\u1ebfu b\u1ea1n ch\u01b0a c\u00f3 d\u1ef1 \u00e1n, h\u00e3y t\u1ea1o m\u1ed9t d\u1ef1 \u00e1n m\u1edbi.<\/li>\n\n\n\n<li>Trong d\u1ef1 \u00e1n c\u1ee7a b\u1ea1n, h\u00e3y t\u00ecm ki\u1ebfm v\u00e0 k\u00edch ho\u1ea1t &#8220;Generative Language API&#8221;.<\/li>\n\n\n\n<li>Sau khi k\u00edch ho\u1ea1t, truy c\u1eadp v\u00e0o m\u1ee5c &#8220;Credentials&#8221; (Th\u00f4ng tin x\u00e1c th\u1ef1c).<\/li>\n\n\n\n<li>Nh\u1ea5p v\u00e0o &#8220;Create credentials&#8221; (T\u1ea1o th\u00f4ng tin x\u00e1c th\u1ef1c) v\u00e0 ch\u1ecdn &#8220;API key&#8221;.<\/li>\n\n\n\n<li>Sao ch\u00e9p API key m\u00e0 b\u1ea1n v\u1eeba t\u1ea1o. H\u00e3y gi\u1eef API key n\u00e0y an to\u00e0n v\u00e0 kh\u00f4ng chia s\u1ebb n\u00f3 c\u00f4ng khai.<\/li>\n<\/ol>\n\n\n\n<p><strong>B\u01b0\u1edbc 2: C\u00e0i \u0111\u1eb7t HTTP Client cho PHP<\/strong><\/p>\n\n\n\n<p>PHP c\u00f3 nhi\u1ec1u th\u01b0 vi\u1ec7n HTTP client m\u1ea1nh m\u1ebd m\u00e0 b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng. M\u1ed9t trong nh\u1eefng th\u01b0 vi\u1ec7n ph\u1ed5 bi\u1ebfn v\u00e0 d\u1ec5 s\u1eed d\u1ee5ng l\u00e0 <strong>Guzzle HTTP<\/strong>. B\u1ea1n c\u00f3 th\u1ec3 c\u00e0i \u0111\u1eb7t Guzzle b\u1eb1ng Composer:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\ncomposer require guzzlehttp\/guzzle\n<\/pre><\/div>\n\n\n<p>\u0110\u1ea3m b\u1ea3o b\u1ea1n \u0111\u00e3 c\u00e0i \u0111\u1eb7t Composer tr\u00ean h\u1ec7 th\u1ed1ng c\u1ee7a m\u00ecnh. N\u1ebfu ch\u01b0a, b\u1ea1n c\u00f3 th\u1ec3 t\u1ea3i v\u00e0 c\u00e0i \u0111\u1eb7t t\u1eeb <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/getcomposer.org\/\">trang ch\u1ee7 c\u1ee7a Composer<\/a>.<\/p>\n\n\n\n<p><strong>B\u01b0\u1edbc 3: X\u00e2y d\u1ef1ng h\u00e0m t\u01b0\u01a1ng t\u00e1c v\u1edbi API c\u1ee7a Gemini<\/strong><\/p>\n\n\n\n<p>B\u00e2y gi\u1edd, b\u1ea1n c\u00f3 th\u1ec3 t\u1ea1o m\u1ed9t h\u00e0m PHP \u0111\u1ec3 g\u1eedi y\u00eau c\u1ea7u \u0111\u1ebfn API c\u1ee7a Gemini. D\u01b0\u1edbi \u0111\u00e2y l\u00e0 m\u1ed9t v\u00ed d\u1ee5 c\u01a1 b\u1ea3n \u0111\u1ec3 g\u1eedi m\u1ed9t y\u00eau c\u1ea7u t\u1ea1o v\u0103n b\u1ea3n (text generation):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\nrequire &#039;vendor\/autoload.php&#039;; \/\/ \u0110\u1ea3m b\u1ea3o \u0111\u01b0\u1eddng d\u1eabn \u0111\u1ebfn autoloader c\u1ee7a Composer l\u00e0 \u0111\u00fang\n\nuse GuzzleHttp\\Client;\n\nfunction generateTextWithGemini(string $prompt, string $apiKey): ?string\n{\n    $client = new Client(&#x5B;\n        &#039;base_uri&#039; =&gt; &#039;https:\/\/generativelanguage.googleapis.com\/v1beta\/&#039;,\n        &#039;timeout&#039; =&gt; 10, \/\/ Th\u1eddi gian ch\u1edd t\u1ed1i \u0111a cho m\u1ed7i y\u00eau c\u1ea7u (gi\u00e2y)\n    ]);\n\n    try {\n        $response = $client-&gt;post(&#039;models\/gemini-2.0-flash:generateContent?key=&#039; . $apiKey , &#x5B;\n            &#039;headers&#039; =&gt; &#x5B;&#039;Content-Type&#039; =&gt; &#039;application\/json&#039;],\n            &#039;json&#039; =&gt; &#x5B;\n                &#039;contents&#039; =&gt; &#x5B;\n                    &#x5B;\n                        &#039;parts&#039; =&gt; &#x5B;&#x5B;&#039;text&#039; =&gt; $prompt]],\n                    ],\n                ],\n            ],\n        ]);\n\n        $body = $response-&gt;getBody();\n        $data = json_decode($body, true);\n\n        \/\/ Ki\u1ec3m tra xem c\u00f3 d\u1eef li\u1ec7u ph\u1ea3n h\u1ed3i v\u00e0 c\u00f3 text \u0111\u01b0\u1ee3c t\u1ea1o hay kh\u00f4ng\n        if (isset($data&#x5B;&#039;candidates&#039;]&#x5B;0]&#x5B;&#039;content&#039;]&#x5B;&#039;parts&#039;]&#x5B;0]&#x5B;&#039;text&#039;])) {\n            return $data&#x5B;&#039;candidates&#039;]&#x5B;0]&#x5B;&#039;content&#039;]&#x5B;&#039;parts&#039;]&#x5B;0]&#x5B;&#039;text&#039;];\n        } else {\n            return null; \/\/ Ho\u1eb7c x\u1eed l\u00fd l\u1ed7i kh\u00e1c t\u00f9y theo nhu c\u1ea7u\n        }\n\n    } catch (\\GuzzleHttp\\Exception\\GuzzleException $e) {\n        \/\/ X\u1eed l\u00fd l\u1ed7i khi g\u1ecdi API\n        error_log(&quot;L\u1ed7i khi g\u1ecdi API Gemini: &quot; . $e-&gt;getMessage());\n        return null;\n    }\n}\n\n\/\/ S\u1eed d\u1ee5ng h\u00e0m\n$apiKey = &#039;YOUR_API_KEY&#039;; \/\/ Thay YOUR_API_KEY b\u1eb1ng API key th\u1ef1c t\u1ebf c\u1ee7a b\u1ea1n\n$userPrompt = &#039;Vi\u1ebft m\u1ed9t \u0111o\u1ea1n th\u01a1 ng\u1eafn v\u1ec1 v\u1ebb \u0111\u1eb9p c\u1ee7a H\u1ed3 G\u01b0\u01a1m.&#039;;\n$generatedText = generateTextWithGemini($userPrompt, $apiKey);\n\nif ($generatedText !== null) {\n    echo &quot;C\u00e2u h\u1ecfi: &quot; . htmlspecialchars($userPrompt) . &quot;&lt;br&gt;&quot;;\n    echo &quot;C\u00e2u tr\u1ea3 l\u1eddi t\u1eeb Gemini: &quot; . nl2br(htmlspecialchars($generatedText));\n} else {\n    echo &quot;Kh\u00f4ng th\u1ec3 t\u1ea1o v\u0103n b\u1ea3n t\u1eeb Gemini.&quot;;\n}\n\n?&gt;\n<\/pre><\/div>\n\n\n<p><strong>Gi\u1ea3i th\u00edch \u0111o\u1ea1n code:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><code>require 'vendor\/autoload.php';<\/code><\/strong>: D\u00f2ng n\u00e0y bao g\u1ed3m autoloader c\u1ee7a Composer \u0111\u1ec3 c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng c\u00e1c th\u01b0 vi\u1ec7n \u0111\u00e3 c\u00e0i \u0111\u1eb7t.<\/li>\n\n\n\n<li><strong><code>use GuzzleHttp\\Client;<\/code><\/strong>: Khai b\u00e1o l\u1edbp <code>Client<\/code> t\u1eeb th\u01b0 vi\u1ec7n Guzzle HTTP.<\/li>\n\n\n\n<li><strong><code>generateTextWithGemini(string $prompt, string $apiKey): ?string<\/code><\/strong>: H\u00e0m n\u00e0y nh\u1eadn v\u00e0o prompt (n\u1ed9i dung b\u1ea1n mu\u1ed1n Gemini x\u1eed l\u00fd) v\u00e0 API key, sau \u0111\u00f3 tr\u1ea3 v\u1ec1 chu\u1ed7i v\u0103n b\u1ea3n \u0111\u01b0\u1ee3c t\u1ea1o ho\u1eb7c <code>null<\/code> n\u1ebfu c\u00f3 l\u1ed7i.<\/li>\n\n\n\n<li><strong><code>$client = new Client([...])<\/code><\/strong>: Kh\u1edfi t\u1ea1o m\u1ed9t instance c\u1ee7a Guzzle HTTP client v\u1edbi c\u1ea5u h\u00ecnh base URI c\u1ee7a API Gemini v\u00e0 th\u1eddi gian ch\u1edd.<\/li>\n\n\n\n<li><strong><code>$client->post(...)<\/code><\/strong>: G\u1eedi m\u1ed9t y\u00eau c\u1ea7u POST \u0111\u1ebfn endpoint <code>models\/gemini-pro:generateContent<\/code>.\n<ul class=\"wp-block-list\">\n<li><code>headers<\/code>: \u0110\u1eb7t header <code>Content-Type<\/code> l\u00e0 <code>application\/json<\/code> v\u00ec ch\u00fang ta \u0111ang g\u1eedi d\u1eef li\u1ec7u JSON.<\/li>\n\n\n\n<li><code>json<\/code>: \u0110\u1ecbnh d\u1ea1ng d\u1eef li\u1ec7u y\u00eau c\u1ea7u d\u01b0\u1edbi d\u1ea1ng JSON. Trong tr\u01b0\u1eddng h\u1ee3p n\u00e0y, ch\u00fang ta g\u1eedi m\u1ed9t <code>contents<\/code> array ch\u1ee9a m\u1ed9t ph\u1ea7n t\u1eed l\u00e0 m\u1ed9t <code>parts<\/code> array, v\u00e0 m\u1ed7i ph\u1ea7n t\u1eed c\u1ee7a <code>parts<\/code> l\u00e0 m\u1ed9t object ch\u1ee9a <code>text<\/code> v\u1edbi n\u1ed9i dung prompt.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>$response->getBody()<\/code><\/strong>: L\u1ea5y ph\u1ea7n body c\u1ee7a ph\u1ea3n h\u1ed3i t\u1eeb API.<\/li>\n\n\n\n<li><strong><code>json_decode($body, true)<\/code><\/strong>: Gi\u1ea3i m\u00e3 chu\u1ed7i JSON ph\u1ea3n h\u1ed3i th\u00e0nh m\u1ed9t m\u1ea3ng PHP.<\/li>\n\n\n\n<li><strong>Ki\u1ec3m tra d\u1eef li\u1ec7u ph\u1ea3n h\u1ed3i<\/strong>: \u0110o\u1ea1n code ki\u1ec3m tra xem ph\u1ea3n h\u1ed3i c\u00f3 ch\u1ee9a d\u1eef li\u1ec7u mong mu\u1ed1n (<code>candidates[0]['content']['parts'][0]['text']<\/code>) hay kh\u00f4ng.<\/li>\n\n\n\n<li><strong><code>try...catch<\/code><\/strong>: S\u1eed d\u1ee5ng kh\u1ed1i <code>try...catch<\/code> \u0111\u1ec3 x\u1eed l\u00fd c\u00e1c exception c\u00f3 th\u1ec3 x\u1ea3y ra trong qu\u00e1 tr\u00ecnh g\u1ecdi API (v\u00ed d\u1ee5: l\u1ed7i m\u1ea1ng, l\u1ed7i server).<\/li>\n\n\n\n<li><strong>S\u1eed d\u1ee5ng h\u00e0m<\/strong>: Ph\u1ea7n cu\u1ed1i c\u1ee7a script minh h\u1ecda c\u00e1ch g\u1ecdi h\u00e0m <code>generateTextWithGemini<\/code> v\u1edbi m\u1ed9t prompt v\u00ed d\u1ee5 v\u00e0 in ra k\u1ebft qu\u1ea3.<\/li>\n<\/ol>\n\n\n\n<p><strong>C\u00e1c endpoint kh\u00e1c c\u1ee7a Gemini API:<\/strong><\/p>\n\n\n\n<p>Ngo\u00e0i vi\u1ec7c t\u1ea1o v\u0103n b\u1ea3n, Gemini c\u00f2n c\u00f3 c\u00e1c endpoint kh\u00e1c cho c\u00e1c t\u00e1c v\u1ee5 kh\u00e1c, v\u00ed d\u1ee5 nh\u01b0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>models\/gemini-pro-vision:generateContent<\/code><\/strong>: \u0110\u1ec3 x\u1eed l\u00fd c\u1ea3 v\u0103n b\u1ea3n v\u00e0 h\u00ecnh \u1ea3nh (multimodal). B\u1ea1n s\u1ebd c\u1ea7n \u0111i\u1ec1u ch\u1ec9nh c\u1ea5u tr\u00fac JSON trong ph\u1ea7n <code>json<\/code> c\u1ee7a y\u00eau c\u1ea7u \u0111\u1ec3 bao g\u1ed3m c\u1ea3 d\u1eef li\u1ec7u h\u00ecnh \u1ea3nh (th\u01b0\u1eddng l\u00e0 base64 encoded).<\/li>\n\n\n\n<li><strong><code>models\/{model}:streamGenerateContent<\/code><\/strong>: \u0110\u1ec3 nh\u1eadn ph\u1ea3n h\u1ed3i theo lu\u1ed3ng (streaming). \u0110i\u1ec1u n\u00e0y ph\u1ee9c t\u1ea1p h\u01a1n m\u1ed9t ch\u00fat trong vi\u1ec7c x\u1eed l\u00fd ph\u1ea3n h\u1ed3i.<\/li>\n<\/ul>\n\n\n\n<p>B\u1ea1n c\u00f3 th\u1ec3 tham kh\u1ea3o t\u00e0i li\u1ec7u ch\u00ednh th\u1ee9c c\u1ee7a Google Generative AI API \u0111\u1ec3 bi\u1ebft th\u00eam chi ti\u1ebft v\u1ec1 c\u00e1c endpoint v\u00e0 c\u1ea5u tr\u00fac d\u1eef li\u1ec7u: <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/ai.google.dev\/docs\">https:\/\/ai.google.dev\/docs<\/a><\/p>\n\n\n\n<p><strong>L\u01b0u \u00fd quan tr\u1ecdng:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>B\u1ea3o m\u1eadt API Key:<\/strong> Tuy\u1ec7t \u0111\u1ed1i kh\u00f4ng nh\u00fang tr\u1ef1c ti\u1ebfp API key v\u00e0o m\u00e3 ngu\u1ed3n client-side (v\u00ed d\u1ee5: JavaScript). H\u00e3y lu\u00f4n x\u1eed l\u00fd API key \u1edf ph\u00eda server-side (PHP trong tr\u01b0\u1eddng h\u1ee3p n\u00e0y).<\/li>\n\n\n\n<li><strong>X\u1eed l\u00fd l\u1ed7i:<\/strong> \u0110o\u1ea1n code v\u00ed d\u1ee5 ch\u1ec9 x\u1eed l\u00fd l\u1ed7i c\u01a1 b\u1ea3n. Trong \u1ee9ng d\u1ee5ng th\u1ef1c t\u1ebf, b\u1ea1n n\u00ean x\u1eed l\u00fd l\u1ed7i chi ti\u1ebft h\u01a1n (v\u00ed d\u1ee5: ghi log, th\u00f4ng b\u00e1o cho ng\u01b0\u1eddi d\u00f9ng).<\/li>\n\n\n\n<li><strong>Gi\u1edbi h\u1ea1n v\u00e0 chi ph\u00ed:<\/strong> H\u00e3y l\u01b0u \u00fd v\u1ec1 c\u00e1c gi\u1edbi h\u1ea1n s\u1eed d\u1ee5ng v\u00e0 chi ph\u00ed li\u00ean quan \u0111\u1ebfn vi\u1ec7c s\u1eed d\u1ee5ng Google Generative Language API.<\/li>\n\n\n\n<li><strong>Input Validation:<\/strong> Lu\u00f4n ki\u1ec3m tra v\u00e0 l\u00e0m s\u1ea1ch d\u1eef li\u1ec7u \u0111\u1ea7u v\u00e0o (prompt) t\u1eeb ng\u01b0\u1eddi d\u00f9ng \u0111\u1ec3 tr\u00e1nh c\u00e1c v\u1ea5n \u0111\u1ec1 b\u1ea3o m\u1eadt ho\u1eb7c h\u00e0nh vi kh\u00f4ng mong mu\u1ed1n.<\/li>\n\n\n\n<li><strong>Asynchronous Requests:<\/strong> \u0110\u1ed1i v\u1edbi c\u00e1c \u1ee9ng d\u1ee5ng c\u00f3 l\u01b0u l\u01b0\u1ee3ng truy c\u1eadp l\u1edbn, b\u1ea1n c\u00f3 th\u1ec3 c\u00e2n nh\u1eafc s\u1eed d\u1ee5ng c\u00e1c th\u01b0 vi\u1ec7n PHP h\u1ed7 tr\u1ee3 asynchronous HTTP requests \u0111\u1ec3 kh\u00f4ng l\u00e0m ch\u1eadm qu\u00e1 tr\u00ecnh x\u1eed l\u00fd c\u1ee7a server.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hi\u1ec7n t\u1ea1i Google ch\u01b0a cung c\u1ea5p m\u1ed9t SDK ch\u00ednh th\u1ee9c d\u00e0nh ri\u00eang cho PHP \u0111\u1ec3 t\u01b0\u01a1ng t\u00e1c tr\u1ef1c ti\u1ebfp v\u1edbi [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":9827,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[212],"tags":[],"class_list":["post-9823","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php-thu-thuat"],"views":1687,"_links":{"self":[{"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/posts\/9823","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/comments?post=9823"}],"version-history":[{"count":4,"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/posts\/9823\/revisions"}],"predecessor-version":[{"id":9828,"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/posts\/9823\/revisions\/9828"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/media\/9827"}],"wp:attachment":[{"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/media?parent=9823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/categories?post=9823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tapchicntt.com\/rest-api\/wp\/v2\/tags?post=9823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}