<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: CHENG QIAN</title>
    <description>The latest articles on Forem by CHENG QIAN (@cheng_qian_8382fdc61158ce).</description>
    <link>https://forem.com/cheng_qian_8382fdc61158ce</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3453948%2F351d79e8-4c4a-4240-9cee-7ff3e3263f66.png</url>
      <title>Forem: CHENG QIAN</title>
      <link>https://forem.com/cheng_qian_8382fdc61158ce</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/cheng_qian_8382fdc61158ce"/>
    <language>en</language>
    <item>
      <title>Timestamps Explained: Decoding the Digital World’s Hidden Timekeeper</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Wed, 15 Apr 2026 02:52:29 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/timestamps-explained-decoding-the-digital-worlds-hidden-timekeeper-2k84</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/timestamps-explained-decoding-the-digital-worlds-hidden-timekeeper-2k84</guid>
      <description>&lt;p&gt;In daily life, we’re accustomed to reading time as 2026-04-15 14:30:00. But behind the scenes of computer systems, network protocols, and data storage, time is often compressed into a seemingly random string of numbers—the Timestamp. It’s a foundational concept for developers and an invisible cornerstone of how the modern internet operates efficiently.&lt;br&gt;
🔍 &lt;strong&gt;The Core Principle of Timestamps&lt;/strong&gt;&lt;br&gt;
At its core, a timestamp is a sequential count of time elapsed from a fixed starting point. The most widely adopted standard in the IT industry is the Unix Timestamp, which records the number of seconds (or milliseconds) since the Unix Epoch: January 1, 1970, 00:00:00 UTC.&lt;br&gt;
For example, 1744675800 isn’t a random code—it precisely maps to a specific moment in time. The year 1970 was chosen simply because Unix was developed in the late 1960s, and engineers needed a clean "year zero." This elegant standard was later adopted by Linux, macOS, iOS, Android, and virtually every major programming language and database, becoming the de facto global norm.&lt;br&gt;
📏 &lt;strong&gt;Common Precision Formats&lt;/strong&gt;&lt;br&gt;
10 digits: Second-level precision (e.g., 1744675800). Widely used in backend APIs and relational databases.&lt;br&gt;
13 digits: Millisecond-level precision (e.g., 1744675800123). Preferred in frontend development, mobile apps, and high-resolution logging.&lt;br&gt;
Scientific or financial systems may use microseconds (16 digits) or nanoseconds (19 digits), but the underlying logic remains identical.&lt;br&gt;
💡 &lt;strong&gt;Why Computers Prefer Timestamps&lt;/strong&gt;&lt;br&gt;
If humans prefer readable date strings, why do machines store raw numbers? The answer lies in standardization, computational efficiency, and cross-platform compatibility:&lt;br&gt;
Timezone Agnostic: Timestamps are strictly UTC-based. Developers never need to wrestle with daylight saving time, regional offsets, or locale-specific quirks at the data layer.&lt;br&gt;
Numerical Comparison = Chronological Order: Sorting, calculating time differences, or verifying event sequences reduces to basic arithmetic. Extremely fast and deterministic.&lt;br&gt;
Compact &amp;amp; Index-Friendly: Integers consume far less storage than strings. Databases index and query numeric fields significantly faster than text.&lt;br&gt;
Auditability &amp;amp; Traceability: In log auditing, distributed transactions, blockchain, and payment gateways, timestamps are critical for reconstructing event timelines and debugging race conditions.&lt;br&gt;
🛠️ &lt;strong&gt;Real-World Development Scenarios&lt;/strong&gt;&lt;br&gt;
API Design: Return created_at: 1744675800, letting the frontend or client handle local timezone conversion and formatting.&lt;br&gt;
Caching &amp;amp; Expiration: Redis TTL, JWT token validation, and session timeouts all rely on straightforward timestamp math.&lt;br&gt;
Logging &amp;amp; Monitoring: Tools like nginx, ELK Stack, and Prometheus use timestamps as the X-axis to correlate distributed system events.&lt;br&gt;
Data Cleaning &amp;amp; Integration: When merging datasets from multiple sources, converting everything to timestamps eliminates format conflicts like 04/15/2026 vs 15-04-2026 vs April 15.&lt;br&gt;
While syntax varies across languages (Date.now() in JavaScript, time.time() in Python, System.currentTimeMillis() in Java), the underlying numeric standard remains fully interoperable.&lt;br&gt;
🔄 &lt;strong&gt;How to Convert &amp;amp; Use Timestamps&lt;/strong&gt;&lt;br&gt;
Manually converting long number strings is impractical and error-prone. Developers typically rely on:&lt;br&gt;
Built-in language libraries (e.g., new Date(timestamp * 1000))&lt;br&gt;
CLI utilities (e.g., date -d @1744675800 on Linux/macOS)&lt;br&gt;
Dedicated online converters&lt;br&gt;
For daily debugging, cross-timezone collaboration, report generation, or quick verification, a reliable, precise, no-login converter saves significant time. A high-quality tool should offer:&lt;br&gt;
✅ Seamless second/millisecond switching&lt;br&gt;
✅ Real-time UTC vs. local timezone comparison&lt;br&gt;
✅ Custom output formats (ISO 8601, RFC 2822, human-readable, etc.)&lt;br&gt;
✅ One-click copy, ready to paste into code or documents&lt;br&gt;
⏱️ Timestamps may look like cold, raw data, but they are the vital bridge between human time perception and machine logic. Whether you’re a software engineer, data analyst, QA tester, or a professional who occasionally handles time-sensitive data, mastering timestamp conversion will streamline your workflows and reduce debugging friction.&lt;br&gt;
If you’re looking for a lightweight, accurate, and instantly accessible timestamp converter, feel free to try the online tool I built:&lt;br&gt;
&lt;a href="https://mantools.top/index/mtindex/timestamp.html" rel="noopener noreferrer"&gt;https://mantools.top/index/mtindex/timestamp.html&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Delete the Image Files, Yet the Website Still Displays? Revealing the "Magic" of Turning Images into Strings</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Sun, 29 Mar 2026 05:19:33 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/delete-the-image-files-yet-the-website-still-displays-revealing-the-magic-of-turning-images-jch</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/delete-the-image-files-yet-the-website-still-displays-revealing-the-magic-of-turning-images-jch</guid>
      <description>&lt;p&gt;Have you ever encountered this awkward situation:&lt;br&gt;
You carefully wrote an HTML webpage, complete with beautiful icons and photos. But when you send the folder to a colleague or deploy it to a server, they open it and see—broken image icons everywhere ❌.&lt;br&gt;
The reason? The image path was wrong, or the image files were missing during transfer.&lt;br&gt;
What if I told you that you actually don't need image files at all? You can turn an image into a string of "gibberish" characters, write it directly into your code, and the webpage will display the image normally. One single file can handle everything. Would you believe it?&lt;br&gt;
This isn't magic; it's a very practical trick in front-end development: Base64 Image Encoding.&lt;br&gt;
Today, let's explain this "black technology" to those who don't know you can display images using strings.&lt;br&gt;
🤔 What is Base64?&lt;br&gt;
Simply put, images in a computer are essentially binary data (0s and 1s), while webpage code is text.&lt;br&gt;
Base64 is a "translation rule" that converts binary image data into pure text characters (such as A-Z, a-z, 0-9, +, /).&lt;br&gt;
Once an image becomes text, it can be stuffed directly into HTML, CSS, or JSON data just like ordinary words, no longer relying on external files.&lt;br&gt;
🪄 Witness the Magic Moment&lt;br&gt;
Usually, we reference images like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Requires an external file logo.png --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"images/logo.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After using Base64, it becomes this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- No external files needed, the string IS the image --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👀 See that long iVBORw0KGgo...? That is the image itself!&lt;br&gt;
You can try copying the code above into a new .html file and opening it in your browser. Even if you don't have any image files on hand, the icon will still display!&lt;br&gt;
🚀 Why Do This? (Three Major Benefits)&lt;br&gt;
Since the string is so long, why bother? Because in specific scenarios, it's incredibly useful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;True "Single File" Portability
If you want to send an HTML report with styles via email, or create an offline demo page, embedding images as Base64 means the recipient only needs one file to open it perfectly. No more awkward "missing image" situations.&lt;/li&gt;
&lt;li&gt;Reduce HTTP Requests
When a webpage loads, every additional image means the browser makes another request to the server. If your page has 20 icons, that's 20 requests.
Converting them to Base64 and merging them into CSS means the browser only requests 1 file, which can actually speed up loading.&lt;/li&gt;
&lt;li&gt;Avoid Path Errors
No paths means no 404 Not Found. No matter where you place your webpage, the images go with the code. They never get lost.
⚠️ Warning! Not All Images Are Suitable
Although this trick is cool, don't abuse it!
❌ Don't use for large images: Base64 encoding increases file size by approximately 33%. If you convert a 1MB photo to Base64, your code becomes huge, slowing down the webpage.
❌ Don't use for frequently changing images: Since the image is embedded in the code, every time you change the image, you have to change the code. You also lose the benefit of browser "image caching."
✅ Best Use Cases:
Small icons (less than 10KB)
Simple Logos
Images in email templates
Demo pages that need to be distributed as a single file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🛠️ How Do I Convert an Image to a String?&lt;/p&gt;

&lt;p&gt;You don't need to write it by hand (that would be exhausting). &lt;/p&gt;

&lt;p&gt;There are many free tools for one-click conversion:&lt;/p&gt;

&lt;p&gt;Online Converters: mantools.top online website tools&lt;br&gt;
&lt;a href="https://mantools.top/index/mtindex/imgtobs64.html" rel="noopener noreferrer"&gt;https://mantools.top/index/mtindex/imgtobs64.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many websites allow you to upload an image and generate the string instantly.&lt;/p&gt;

&lt;p&gt;VS Code Extensions: If you code, install an "Image to Base64" plugin. Right-click the image to convert it.&lt;br&gt;
Command Line: Mac/Linux users can simply use the base64 -i image.png command.&lt;/p&gt;

&lt;p&gt;💡 Summary&lt;br&gt;
Base64 Image Encoding is like putting a "text coat" on an image, allowing it to seamlessly integrate into the world of code.&lt;br&gt;
For small icons and single-file distribution, it's a godsend.&lt;br&gt;
For large photos, please stick to external files.&lt;br&gt;
Next time you need to send an HTML file to a friend that "will never break images," try this trick. It will definitely make their eyes light up! 😎&lt;br&gt;
Found this useful? Feel free to share it with that friend who always loses image paths!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>web3</category>
      <category>html</category>
    </item>
    <item>
      <title>The problem where the TP5 IoT project has been unable to get the request parameters</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Sun, 25 Jan 2026 02:06:53 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/the-problem-where-the-tp5-iot-project-has-been-unable-to-get-the-request-parameters-p91</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/the-problem-where-the-tp5-iot-project-has-been-unable-to-get-the-request-parameters-p91</guid>
      <description>&lt;p&gt;During an IoT project, when using ThinkPHP 5.0, the conventional framework methods failed to retrieve the parameters sent by the device's request—they always returned empty.&lt;/p&gt;

&lt;p&gt;Eventually, the issue was resolved by using native PHP to obtain the request body. That is, parameters were fetched using PHP's native methods, resulting in a string, which was then converted into an object for further use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;P.S. If you're looking for handy free utilities to assist with web development—like Base64 encoding, QR code generation, favicon creation, or text formatting—feel free to explore &lt;a href="https://mantools.top/" rel="noopener noreferrer"&gt;https://mantools.top/&lt;/a&gt;. It’s a lightweight, no-signup toolkit built for developers and creators. Hope it saves you a few minutes today! &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Top 5 Best World Time Zone Converters &amp; Global Clock Tools in 2026</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Wed, 21 Jan 2026 06:28:00 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/top-5-best-world-time-zone-converters-global-clock-tools-in-2026-46ki</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/top-5-best-world-time-zone-converters-global-clock-tools-in-2026-46ki</guid>
      <description>&lt;p&gt;Keeping track of global time zones is essential for remote teams, international travelers, and online collaborators. Whether you're scheduling a meeting across continents or just curious what time it is in Tokyo right now, having a reliable world clock tool makes all the difference. After testing dozens of options, we’ve curated the top 5 best world time zone tools—and one stands out as the clear winner.&lt;/p&gt;

&lt;p&gt;🥇 1. ManTools World Time – &lt;a href="https://mantools.top/index/mtindex/worldtime.html" rel="noopener noreferrer"&gt;mantools.top&lt;/a&gt;&lt;br&gt;
Why it’s #1:&lt;br&gt;
ManTools offers one of the cleanest, most intuitive interfaces for checking real-time clocks across major global cities. What sets it apart is its color-coded time status legend (Morning, Noon, Afternoon, Evening/Night, Late Night), which instantly shows not just the hour—but the context of the day in each region.&lt;/p&gt;

&lt;p&gt;✅ Real-time global clocks with clear visual indicators&lt;br&gt;
✅ Lightweight, fast-loading, and mobile-friendly&lt;br&gt;
✅ No ads or pop-ups—just pure utility&lt;br&gt;
✅ Focus on key countries without overwhelming clutter&lt;br&gt;
Perfect for quick glances or planning cross-timezone coordination. If you need to know whether it’s too late to call someone in Berlin or if your team in Sydney is starting their workday, ManTools delivers clarity at a glance.&lt;/p&gt;

&lt;p&gt;👉 Visit &lt;a href="https://mantools.top/index/mtindex/worldtime.html" rel="noopener noreferrer"&gt;ManTools World Time&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🥈 2. World Time Buddy (&lt;a href="http://worldtimebuddy.com" rel="noopener noreferrer"&gt;worldtimebuddy.com&lt;/a&gt;)&lt;br&gt;
A favorite among project managers, World Time Buddy excels at comparing multiple time zones side-by-side and includes drag-and-drop scheduling. It integrates with Google Calendar and supports daylight saving adjustments. However, the interface feels slightly dated, and free users see ads.&lt;/p&gt;

&lt;p&gt;🥉 3. Time.is (&lt;a href="http://time.is" rel="noopener noreferrer"&gt;time.is&lt;/a&gt;)&lt;br&gt;
Super minimal and ultra-precise, Time.is displays the exact atomic time for any city with millisecond accuracy. Great for tech-savvy users who value precision over visuals—but it lacks contextual info like “is it morning there?” or regional overviews.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Google Search (Just Type “Time in [City]”)&lt;br&gt;
Google’s built-in time feature is surprisingly robust. Simply search “current time in Tokyo,” and you’ll get an instant answer. While convenient, it’s not designed for comparing multiple zones simultaneously or visualizing global time patterns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Every Time Zone (&lt;a href="http://everytimezone.com" rel="noopener noreferrer"&gt;everytimezone.com&lt;/a&gt;)&lt;br&gt;
Designed by developers for developers, this tool visualizes the entire day across time zones using a horizontal timeline. Excellent for planning releases or global launches—but less user-friendly for casual users.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Final Verdict&lt;br&gt;
For simplicity, speed, and smart design, &lt;a href="https://mantools.top/index/mtindex/worldtime.html" rel="noopener noreferrer"&gt;ManTools World Time&lt;/a&gt; is our top recommendation in 2026. It strips away the noise and gives you exactly what you need: a clear, color-coded snapshot of the world’s current time—no signups, no distractions.&lt;/p&gt;

&lt;p&gt;Bookmark it. You’ll use it more than you think.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>uniAPP报错：v-for 暂不支持循环数据： (env: Windows,mp,1.06.2307260； lib: 3.12.0)</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Mon, 12 Jan 2026 04:03:26 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/uniappbao-cuo-v-for-zan-bu-zhi-chi-xun-huan-shu-ju-env-windowsmp1062307260-lib-3120-2ng7</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/uniappbao-cuo-v-for-zan-bu-zhi-chi-xun-huan-shu-ju-env-windowsmp1062307260-lib-3120-2ng7</guid>
      <description>&lt;p&gt;uniAPP报错：v-for 暂不支持循环数据： (env: Windows,mp,1.06.2307260; lib: 3.12.0)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fes3f8ybuyxybssk7l6fa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fes3f8ybuyxybssk7l6fa.png" alt=" " width="399" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;报错情景是外层有循环列表，里层元素里&lt;strong&gt;有点击事件&lt;/strong&gt;，点击事件把一个循环的数组元素当作参数传入了。然后莫名其妙的报这个错。&lt;/p&gt;

&lt;p&gt;最后，发现原因是：外层循环的时候 &lt;strong&gt;每个元素的 :key绑定的是一个undefined的属性，改为索引index，或其他比如id等真实存在的属性&lt;/strong&gt;，但是不重复的就可以了&lt;/p&gt;

&lt;p&gt;程序员的免费工具网站 &lt;a href="https://mantools.top/" rel="noopener noreferrer"&gt;https://mantools.top/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Performance Comparison of ThinkPHP 5.1 Applications on Nginx vs. Apache</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Fri, 09 Jan 2026 02:56:40 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/performance-comparison-of-thinkphp-51-applications-on-nginx-vs-apache-4495</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/performance-comparison-of-thinkphp-51-applications-on-nginx-vs-apache-4495</guid>
      <description>&lt;p&gt;Performance Comparison of ThinkPHP 5.1 Applications on Nginx vs. Apache&lt;/p&gt;

&lt;p&gt;As PHP developers, we often face the decision of choosing a web server that best suits our application’s performance, scalability, and maintainability needs. For those using the ThinkPHP 5.1 framework—a popular PHP MVC framework in the Chinese developer community—it’s worth examining how it performs under two of the most widely used web servers: Nginx and Apache.&lt;/p&gt;

&lt;p&gt;In this post, I’ll share benchmark results, configuration insights, and practical considerations when running ThinkPHP 5.1 on both Nginx and Apache, based on real-world testing in a controlled environment.&lt;/p&gt;

&lt;p&gt;🔧 &lt;strong&gt;Test Environment&lt;/strong&gt;&lt;br&gt;
Server OS: Ubuntu 22.04 LTS&lt;br&gt;
CPU: 4 vCPUs&lt;br&gt;
RAM: 8 GB&lt;br&gt;
PHP Version: 7.4 (with OPcache enabled)&lt;br&gt;
ThinkPHP Version: 5.1.41&lt;br&gt;
Web Servers:&lt;br&gt;
Nginx 1.18.0 + PHP-FPM&lt;br&gt;
Apache 2.4.52 + mod_php&lt;br&gt;
Database: MySQL 8.0 (same dataset for both tests)&lt;br&gt;
Load Testing Tool: Apache Bench (ab) and wrk&lt;br&gt;
Test Endpoint: A typical controller action returning JSON data with moderate DB queries&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzk4kq4xkm86nx8pw9qt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzk4kq4xkm86nx8pw9qt.png" alt=" " width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: All tests were run after warm-up and repeated 3 times; averages are reported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Observations&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Request Throughput&lt;br&gt;
Nginx consistently outperformed Apache in handling concurrent requests. Its event-driven, non-blocking architecture handles high concurrency more efficiently—especially beneficial for I/O-heavy ThinkPHP apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory Efficiency&lt;br&gt;
Nginx + PHP-FPM consumes less memory per request compared to Apache’s prefork MPM with mod_php. This makes Nginx more scalable on resource-constrained servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;URL Rewriting &amp;amp; ThinkPHP Routing&lt;br&gt;
ThinkPHP 5.1 relies heavily on URL rewriting for its pathinfo-style routing (e.g., /index.php/index/hello).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Apache: Works out-of-the-box with .htaccess (provided mod_rewrite is enabled).&lt;br&gt;
Nginx: Requires manual rewrite rules in the server block. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;location / {
    if (!-e $request_filename) {
        rewrite ^(.*)$ /index.php?s=$1 last;
        break;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While slightly more configuration is needed for Nginx, the performance payoff is significant.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Static Asset Handling&lt;br&gt;
Nginx serves static files (CSS, JS, images) faster and with lower overhead—ideal for ThinkPHP apps that include public assets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ease of Deployment&lt;br&gt;
Apache’s .htaccess support simplifies shared hosting deployments, but in modern containerized or VPS environments, Nginx configurations are just as manageable—and more performant.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ &lt;strong&gt;Recommendations&lt;/strong&gt;&lt;br&gt;
Choose Nginx if:&lt;br&gt;
You expect high traffic or need better resource efficiency.&lt;br&gt;
You’re deploying on cloud/VPS environments where you control the full stack.&lt;br&gt;
Your app uses many static assets or APIs with concurrent users.&lt;br&gt;
Choose Apache if:&lt;br&gt;
You rely on .htaccess for per-directory config (e.g., shared hosting).&lt;br&gt;
Your team is more familiar with Apache syntax and modules.&lt;br&gt;
You need advanced .htaccess-based security or redirects without server-level access.&lt;br&gt;
🔚 &lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
For most production-grade ThinkPHP 5.1 applications, Nginx paired with PHP-FPM delivers superior performance, lower memory usage, and better scalability compared to Apache with mod_php. While Apache remains a solid choice—especially in legacy or shared environments—modern deployments benefit greatly from Nginx’s architecture.&lt;/p&gt;

&lt;p&gt;That said, always test with your specific workload. Application logic, database design, and caching strategies (e.g., Redis, Memcached) also heavily influence real-world performance.&lt;/p&gt;

&lt;p&gt;Have you deployed ThinkPHP on Nginx or Apache? Share your experiences or optimization tips below! 👇&lt;/p&gt;

&lt;p&gt;P.S. If you're looking for handy free utilities to assist with web development—like Base64 encoding, QR code generation, favicon creation, or text formatting—feel free to explore &lt;a href="https://mantools.top/" rel="noopener noreferrer"&gt;https://mantools.top/&lt;/a&gt;. It’s a lightweight, no-signup toolkit built for developers and creators. Hope it saves you a few minutes today! 😊&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ThinkPHP 5.1 程序在 Nginx 和 Apache 下的性能对比</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Thu, 08 Jan 2026 02:08:44 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/thinkphp-51-cheng-xu-zai-nginx-he-apache-xia-de-xing-neng-dui-bi-53ha</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/thinkphp-51-cheng-xu-zai-nginx-he-apache-xia-de-xing-neng-dui-bi-53ha</guid>
      <description>&lt;p&gt;好的，这个问题非常具体，我们来针对 ThinkPHP 5.1 程序在 Nginx 和 Apache 下的性能表现进行一个深入的分析。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;核心结论（针对TP5.1）&lt;/strong&gt;&lt;br&gt;
在同样运行ThinkPHP 5.1程序的情况下，Nginx的性能（尤其是并发处理能力）通常会比Apache有显著提升，具体表现在：&lt;/p&gt;

&lt;p&gt;高并发场景下： Nginx的请求处理能力（RPS）可能是Apache (prefork模式) 的 1.5倍 到 3倍甚至更高。&lt;br&gt;
资源消耗方面： Nginx的内存占用通常只有Apache (prefork模式) 的 1/2 到 1/5，尤其是在处理大量并发连接时。&lt;br&gt;
响应时间： 在高负载下，Nginx的响应时间更加稳定和快速，而Apache容易因进程耗尽而排队等待。&lt;br&gt;
这个差距的根源不在于ThinkPHP本身，而在于两者服务器架构和与PHP的交互方式。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;原理分析：为什么Nginx更适合TP/PHP程序？&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;架构与PHP处理方式（最关键区别）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgb67qsg3ao89s8yxch3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgb67qsg3ao89s8yxch3.png" alt=" " width="800" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;特性   Nginx + PHP-FPM    Apache (prefork) + mod_php&lt;br&gt;
架构模型     事件驱动、异步非阻塞 进程驱动、同步阻塞&lt;br&gt;
PHP处理    通过FastCGI协议与独立的PHP-FPM进程池通信  将PHP解释器(mod_php模块)嵌入到每个Apache进程中&lt;br&gt;
工作方式    Nginx专精于处理静态文件和转发请求，PHP-FPM专精于执行PHP代码。职责分离。 每个Apache进程本身就是一个“庞然大物”，既处理HTTP协议，又直接执行PHP代码。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;这对TP5.1意味着什么？
内存消耗：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nginx+PHP-FPM: Nginx进程很轻量，PHP-FPM进程虽然占用内存，但数量可控（可配置）。一个TP5.1应用的PHP进程可能占用50MB，10个进程就是500MB。&lt;br&gt;
Apache+mod_php: 每个Apache进程都加载了整个TP5.1框架和mod_php。假设一个进程占80MB，要处理100个并发就需要创建100个进程，总内存消耗高达 8GB！这是Apache prefork模式内存爆炸的根本原因。&lt;br&gt;
并发处理：&lt;/p&gt;

&lt;p&gt;Nginx: 一个Nginx工作进程就能轻松处理上千个并发连接（只是转发），真正消耗资源的后端PHP-FPM进程数量是固定的。&lt;br&gt;
Apache (prefork): “一个连接一个进程”。如果MaxClients设置为256，那么最大并发连接数就是256。超过这个数，新用户就会看到503错误。为了支持更多并发，就必须开启更多进程，导致内存迅速耗尽。&lt;br&gt;
静态文件处理：&lt;/p&gt;

&lt;p&gt;Nginx: 以原生C代码高效处理静态文件（CSS, JS, 图片），速度极快，是TP5.1中/public目录下资源的最佳服务员。&lt;br&gt;
Apache: 也能处理，但需要由一个“臃肿”的、加载了PHP模块的进程来处理，杀鸡用牛刀，效率低下。&lt;br&gt;
量化对比示意图&lt;br&gt;
下图直观展示了两种架构在处理并发请求时的性能差异：&lt;br&gt;
如何为TP5.1选择Web服务器？&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmdwo3c9a2gn3ulx3ps7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmdwo3c9a2gn3ulx3ps7.png" alt=" " width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;场景  推荐方案    理由&lt;br&gt;
开发环境    Apache 或 Nginx 均可 Apache配置简单（.htaccess支持好），Nginx更接近生产环境。按习惯选择。&lt;br&gt;
生产环境（尤其是VPS/云服务器） 强烈推荐 Nginx + PHP-FPM    性能、资源利用率、稳定性全面胜出。是部署PHP应用（包括TP）的事实标准。&lt;br&gt;
共享主机/传统环境   Apache  很多廉价共享主机只支持Apache和它的.htaccess。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;给TP5.1用户的最终建议&lt;/strong&gt;&lt;br&gt;
1、生产环境无脑选 Nginx + PHP-FPM：这是经过无数实践验证的、运行ThinkPHP等PHP框架的最佳组合。你获得的性能提升和资源节省是实实在在的。&lt;/p&gt;

&lt;p&gt;2、如果你必须使用Apache：请尝试将其MPM模式从prefork切换到event，并同样使用PHP-FPM而不是mod_php。这样能大幅缩小与Nginx的性能差距。配置示例 (httpd.conf)：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

# 将PHP请求转发给PHP-FPM
ProxyPassMatch "^/(.*\.php)$" "fcgi://127.0.0.1:9000/path/to/your/tp5/public/$1"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.优化你的TP5.1：无论用什么Web服务器，都请务必开启OPcache和路由缓存，这带来的性能提升可能比更换Web服务器更大。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php think optimize:route
php think optimize:config

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;总结：对于你的TP5.1系统，从Apache切换到Nginx，你很可能感受到的是质的飞跃，特别是在用户量上来之后，服务器会更稳定，响应更快，且能支持更多的同时在线用户。&lt;/p&gt;

&lt;p&gt;程序员的免费工具网站 &lt;a href="https://mantools.top/" rel="noopener noreferrer"&gt;https://mantools.top/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>网站Favicon图标：小图标背后的大作用</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Thu, 08 Jan 2026 02:00:58 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/wang-zhan-favicontu-biao-xiao-tu-biao-bei-hou-de-da-zuo-yong-552k</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/wang-zhan-favicontu-biao-xiao-tu-biao-bei-hou-de-da-zuo-yong-552k</guid>
      <description>&lt;p&gt;在浏览网页时，您可能已经注意到每个网站标签页上都有一个微型图标，这就是Favicon（网站图标）。尽管它尺寸极小，通常只有16x16或32x32像素，却在用户体验和品牌识别中扮演着重要角色。本文将深入探讨Favicon的技术原理、设计要点及其对网站的重要性。&lt;/p&gt;

&lt;p&gt;什么是Favicon？&lt;br&gt;
定义与起源&lt;br&gt;
Favicon（Favorite Icon的缩写）是显示在浏览器标签页、书签列表和历史记录中的小型网站图标。它最早由微软在1997年的Internet Explorer 5中引入，随后成为行业标准。&lt;/p&gt;

&lt;p&gt;技术规格&lt;br&gt;
现代Favicon通常需要满足以下技术要求：&lt;/p&gt;

&lt;p&gt;文件格式：ICO、PNG、GIF、JPEG、SVG&lt;/p&gt;

&lt;p&gt;标准尺寸：16x16、32x32、48x48像素&lt;/p&gt;

&lt;p&gt;色彩模式：RGB，支持alpha通道透明度&lt;/p&gt;

&lt;p&gt;文件大小：建议不超过100KB&lt;/p&gt;

&lt;p&gt;Favicon的技术实现&lt;br&gt;
传统ICO格式&lt;br&gt;
ICO是传统的Favicon格式，其独特之处在于可以包含多个尺寸的图像：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="icon" type="image/x-icon" href="/favicon.ico"&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;现代多尺寸适配&lt;br&gt;
随着高分辨率显示设备的普及，现代网站通常需要提供多种尺寸的Favicon：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"&amp;gt;
&amp;lt;link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"&amp;gt;
&amp;lt;link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;把这些标签放到你的HTML页面里，就会起作用了&lt;/p&gt;

&lt;p&gt;为什么 Favicon 重要？&lt;/p&gt;

&lt;p&gt;提升品牌识别度&lt;br&gt;
在用户同时打开多个标签页时，Favicon 是快速定位目标网站的关键视觉线索。例如，GitHub 的猫头鹰图标、知乎的蓝色问答标志，都能让用户一眼识别。&lt;/p&gt;

&lt;p&gt;增强专业感&lt;br&gt;
缺少 Favicon 的网站在浏览器中会显示默认空白或通用图标，容易让用户产生“临时页面”“测试站点”或“不完整”的印象，影响信任度。&lt;/p&gt;

&lt;p&gt;改善用户体验&lt;br&gt;
书签管理更高效：用户通过图标而非文字快速找到常用网站。&lt;br&gt;
移动端体验：添加到主屏幕的快捷方式依赖高质量图标。&lt;br&gt;
减少 404 请求：若未提供 favicon.ico，浏览器仍会自动请求该路径，导致不必要的 404 错误日志（虽不影响功能，但增加服务器负担）。&lt;/p&gt;

&lt;p&gt;如何生成和部署 Favicon？&lt;/p&gt;

&lt;p&gt;手动方式&lt;br&gt;
1、使用设计工具（如 Photoshop、Figma）创建多尺寸 PNG 图标。&lt;br&gt;
2、用在线工具（如 &lt;a href="https://mantools.top/index/mtindex/favicon.html" rel="noopener noreferrer"&gt;mantools.top&lt;/a&gt; ）将 PNG 合并为 .ico 文件。&lt;br&gt;
&lt;a href="https://mantools.top/index/mtindex/favicon.html" rel="noopener noreferrer"&gt;https://mantools.top/index/mtindex/favicon.html&lt;/a&gt;&lt;br&gt;
3、在 HTML 中添加相应 标签。&lt;br&gt;
4、上传 .ico 文件至网站根目录或指定路径。&lt;br&gt;
href=“/favicon.ico” 是这个ico图标在项目中的地址，是根路径，然后把这个link标签&lt;br&gt;
添加到你的HTML页面里就可以了&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="icon" type="image/x-icon" href="/favicon.ico"&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6edo7kx0ku7ej0c9qsbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6edo7kx0ku7ej0c9qsbu.png" alt=" " width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>uniAPP开发 image 标签的@error事件不被触发调用怎么办</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Sun, 04 Jan 2026 01:21:54 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/uniappkai-fa-image-biao-qian-de-errorshi-jian-bu-bei-hong-fa-diao-yong-zen-yao-ban-1o0g</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/uniappkai-fa-image-biao-qian-de-errorshi-jian-bu-bei-hong-fa-diao-yong-zen-yao-ban-1o0g</guid>
      <description>&lt;p&gt;一开始这种写法是不触发的，就是:src地址是后台拼接好的一整个地址，比如&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;:src="formData.img" &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://www.mantools.top" rel="noopener noreferrer"&gt;http://www.mantools.top/123.png&lt;/a&gt; 如果这个图片不存在，就不会触发@error&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;image :src="formData.img"   mode="aspectFill"  v-show="!mem_img_error" @error="errAvatar"
         class="preview-image" &amp;gt;&amp;lt;/image&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;这个情况，整了我一下午，没整出来。&lt;br&gt;
后来试试用前端拼接这个地址，也就是下面的这种&lt;br&gt;
host变量是在uniAPP里定义好的字符串 &lt;a href="http://www.mantools.top" rel="noopener noreferrer"&gt;http://www.mantools.top&lt;/a&gt;&lt;br&gt;
formData.img是后台获取的图片地址 345.png&lt;br&gt;
这时候，这个图片加载错误了，就会触发@error事件&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;用前端拼接这个地址 :src="host+formData.img"&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;image :src="host+formData.img"   mode="aspectFill"  v-show="!mem_img_error" @error="errAvatar"
         class="preview-image" &amp;gt;&amp;lt;/image&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>uniapp-如何生成二维码超详细，js也可以</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Wed, 19 Nov 2025 05:51:13 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/uniapp-ru-he-sheng-cheng-er-wei-ma-chao-xiang-xi-jsye-ke-yi-116</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/uniapp-ru-he-sheng-cheng-er-wei-ma-chao-xiang-xi-jsye-ke-yi-116</guid>
      <description>&lt;p&gt;uQRCode是一款基于Javascript环境开发的二维码生成插件，适用所有Javascript运行环境的前端应用和Node.js应用。&lt;br&gt;
官方文档： &lt;a href="https://uqrcode.cn/doc" rel="noopener noreferrer"&gt;https://uqrcode.cn/doc&lt;/a&gt;&lt;br&gt;
github地址： &lt;a href="https://github.com/Sansnn/uQRCode" rel="noopener noreferrer"&gt;https://github.com/Sansnn/uQRCode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;一、第一步&lt;br&gt;
(1) 首先需要创建一个js文件，名字为 uqrcode.js , 名字随意;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz88gicr3vlug0jhytcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz88gicr3vlug0jhytcp.png" alt=" " width="226" height="34"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(2) 在你需要的页引入 uqrcode.js文件，到这里都成功了一半；&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5sgjwsa04b4wx1svbh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5sgjwsa04b4wx1svbh6.png" alt=" " width="800" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(3) 温馨提示: 二维码呢是需要在 画布(canvas) 里边展示的，接下来先需要一个画布&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft958gb72mi7798fcyweq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft958gb72mi7798fcyweq.png" alt=" " width="800" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(4) 然后在methods方法里边定义一个函数方法；&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;onLoad(option) {
            console.log(this.obj,123)
            this.qrFun(option.qljyAdvertisementEnrollEntity.adMark)
        },
        methods: {
       qrFun: function(text) {
                UQrcode.make({
                    canvasId: 'qrcode',   //切记canvasId 里边的内容需要跟canvas里边canvas-id="qrcode"的名字一样
                    componentInstance: this,
                    text: text,  //需要转成二维码的内容是后端传过来的，我这里是onLoad传过来的，根                              据自己的需要
                    size: 150,
                    margin: 0,
                    backgroundColor: '#ffffff',
                    foregroundColor: '#000000',
                    fileType: 'jpg',
                    errorCorrectLevel: UQrcode.errorCorrectLevel.H,
                    success: res =&amp;gt; {}
                })
            },
    }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;二级目录&lt;br&gt;
三、uqrcode.js 原码&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// uqrcode.js
//---------------------------------------------------------------------
// github https://github.com/Sansnn/uQRCode
//---------------------------------------------------------------------

let uQRCode = {};

(function() {
    //---------------------------------------------------------------------
    // QRCode for JavaScript
    //
    // Copyright (c) 2009 Kazuhiko Arase
    //
    // URL: http://www.d-project.com/
    //
    // Licensed under the MIT license:
    //   http://www.opensource.org/licenses/mit-license.php
    //
    // The word "QR Code" is registered trademark of 
    // DENSO WAVE INCORPORATED
    //   http://www.denso-wave.com/qrcode/faqpatent-e.html
    //
    //---------------------------------------------------------------------

    //---------------------------------------------------------------------
    // QR8bitByte
    //---------------------------------------------------------------------

    function QR8bitByte(data) {
        this.mode = QRMode.MODE_8BIT_BYTE;
        this.data = data;
    }

    QR8bitByte.prototype = {

        getLength: function(buffer) {
            return this.data.length;
        },

        write: function(buffer) {
            for (var i = 0; i &amp;lt; this.data.length; i++) {
                // not JIS ...
                buffer.put(this.data.charCodeAt(i), 8);
            }
        }
    };

    //---------------------------------------------------------------------
    // QRCode
    //---------------------------------------------------------------------

    function QRCode(typeNumber, errorCorrectLevel) {
        this.typeNumber = typeNumber;
        this.errorCorrectLevel = errorCorrectLevel;
        this.modules = null;
        this.moduleCount = 0;
        this.dataCache = null;
        this.dataList = new Array();
    }

    QRCode.prototype = {

        addData: function(data) {
            var newData = new QR8bitByte(data);
            this.dataList.push(newData);
            this.dataCache = null;
        },

        isDark: function(row, col) {
            if (row &amp;lt; 0 || this.moduleCount &amp;lt;= row || col &amp;lt; 0 || this.moduleCount &amp;lt;= col) {
                throw new Error(row + "," + col);
            }
            return this.modules[row][col];
        },

        getModuleCount: function() {
            return this.moduleCount;
        },

        make: function() {
            // Calculate automatically typeNumber if provided is &amp;lt; 1
            if (this.typeNumber &amp;lt; 1) {
                var typeNumber = 1;
                for (typeNumber = 1; typeNumber &amp;lt; 40; typeNumber++) {
                    var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);

                    var buffer = new QRBitBuffer();
                    var totalDataCount = 0;
                    for (var i = 0; i &amp;lt; rsBlocks.length; i++) {
                        totalDataCount += rsBlocks[i].dataCount;
                    }

                    for (var i = 0; i &amp;lt; this.dataList.length; i++) {
                        var data = this.dataList[i];
                        buffer.put(data.mode, 4);
                        buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
                        data.write(buffer);
                    }
                    if (buffer.getLengthInBits() &amp;lt;= totalDataCount * 8)
                        break;
                }
                this.typeNumber = typeNumber;
            }
            this.makeImpl(false, this.getBestMaskPattern());
        },

        makeImpl: function(test, maskPattern) {

            this.moduleCount = this.typeNumber * 4 + 17;
            this.modules = new Array(this.moduleCount);

            for (var row = 0; row &amp;lt; this.moduleCount; row++) {

                this.modules[row] = new Array(this.moduleCount);

                for (var col = 0; col &amp;lt; this.moduleCount; col++) {
                    this.modules[row][col] = null; //(col + row) % 3;
                }
            }

            this.setupPositionProbePattern(0, 0);
            this.setupPositionProbePattern(this.moduleCount - 7, 0);
            this.setupPositionProbePattern(0, this.moduleCount - 7);
            this.setupPositionAdjustPattern();
            this.setupTimingPattern();
            this.setupTypeInfo(test, maskPattern);

            if (this.typeNumber &amp;gt;= 7) {
                this.setupTypeNumber(test);
            }

            if (this.dataCache == null) {
                this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
            }

            this.mapData(this.dataCache, maskPattern);
        },

        setupPositionProbePattern: function(row, col) {

            for (var r = -1; r &amp;lt;= 7; r++) {

                if (row + r &amp;lt;= -1 || this.moduleCount &amp;lt;= row + r) continue;

                for (var c = -1; c &amp;lt;= 7; c++) {

                    if (col + c &amp;lt;= -1 || this.moduleCount &amp;lt;= col + c) continue;

                    if ((0 &amp;lt;= r &amp;amp;&amp;amp; r &amp;lt;= 6 &amp;amp;&amp;amp; (c == 0 || c == 6)) ||
                        (0 &amp;lt;= c &amp;amp;&amp;amp; c &amp;lt;= 6 &amp;amp;&amp;amp; (r == 0 || r == 6)) ||
                        (2 &amp;lt;= r &amp;amp;&amp;amp; r &amp;lt;= 4 &amp;amp;&amp;amp; 2 &amp;lt;= c &amp;amp;&amp;amp; c &amp;lt;= 4)) {
                        this.modules[row + r][col + c] = true;
                    } else {
                        this.modules[row + r][col + c] = false;
                    }
                }
            }
        },

        getBestMaskPattern: function() {

            var minLostPoint = 0;
            var pattern = 0;

            for (var i = 0; i &amp;lt; 8; i++) {

                this.makeImpl(true, i);

                var lostPoint = QRUtil.getLostPoint(this);

                if (i == 0 || minLostPoint &amp;gt; lostPoint) {
                    minLostPoint = lostPoint;
                    pattern = i;
                }
            }

            return pattern;
        },

        createMovieClip: function(target_mc, instance_name, depth) {

            var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
            var cs = 1;

            this.make();

            for (var row = 0; row &amp;lt; this.modules.length; row++) {

                var y = row * cs;

                for (var col = 0; col &amp;lt; this.modules[row].length; col++) {

                    var x = col * cs;
                    var dark = this.modules[row][col];

                    if (dark) {
                        qr_mc.beginFill(0, 100);
                        qr_mc.moveTo(x, y);
                        qr_mc.lineTo(x + cs, y);
                        qr_mc.lineTo(x + cs, y + cs);
                        qr_mc.lineTo(x, y + cs);
                        qr_mc.endFill();
                    }
                }
            }

            return qr_mc;
        },

        setupTimingPattern: function() {

            for (var r = 8; r &amp;lt; this.moduleCount - 8; r++) {
                if (this.modules[r][6] != null) {
                    continue;
                }
                this.modules[r][6] = (r % 2 == 0);
            }

            for (var c = 8; c &amp;lt; this.moduleCount - 8; c++) {
                if (this.modules[6][c] != null) {
                    continue;
                }
                this.modules[6][c] = (c % 2 == 0);
            }
        },

        setupPositionAdjustPattern: function() {

            var pos = QRUtil.getPatternPosition(this.typeNumber);

            for (var i = 0; i &amp;lt; pos.length; i++) {

                for (var j = 0; j &amp;lt; pos.length; j++) {

                    var row = pos[i];
                    var col = pos[j];

                    if (this.modules[row][col] != null) {
                        continue;
                    }

                    for (var r = -2; r &amp;lt;= 2; r++) {

                        for (var c = -2; c &amp;lt;= 2; c++) {

                            if (r == -2 || r == 2 || c == -2 || c == 2 ||
                                (r == 0 &amp;amp;&amp;amp; c == 0)) {
                                this.modules[row + r][col + c] = true;
                            } else {
                                this.modules[row + r][col + c] = false;
                            }
                        }
                    }
                }
            }
        },

        setupTypeNumber: function(test) {

            var bits = QRUtil.getBCHTypeNumber(this.typeNumber);

            for (var i = 0; i &amp;lt; 18; i++) {
                var mod = (!test &amp;amp;&amp;amp; ((bits &amp;gt;&amp;gt; i) &amp;amp; 1) == 1);
                this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
            }

            for (var i = 0; i &amp;lt; 18; i++) {
                var mod = (!test &amp;amp;&amp;amp; ((bits &amp;gt;&amp;gt; i) &amp;amp; 1) == 1);
                this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
            }
        },

        setupTypeInfo: function(test, maskPattern) {

            var data = (this.errorCorrectLevel &amp;lt;&amp;lt; 3) | maskPattern;
            var bits = QRUtil.getBCHTypeInfo(data);

            // vertical     
            for (var i = 0; i &amp;lt; 15; i++) {

                var mod = (!test &amp;amp;&amp;amp; ((bits &amp;gt;&amp;gt; i) &amp;amp; 1) == 1);

                if (i &amp;lt; 6) {
                    this.modules[i][8] = mod;
                } else if (i &amp;lt; 8) {
                    this.modules[i + 1][8] = mod;
                } else {
                    this.modules[this.moduleCount - 15 + i][8] = mod;
                }
            }

            // horizontal
            for (var i = 0; i &amp;lt; 15; i++) {

                var mod = (!test &amp;amp;&amp;amp; ((bits &amp;gt;&amp;gt; i) &amp;amp; 1) == 1);

                if (i &amp;lt; 8) {
                    this.modules[8][this.moduleCount - i - 1] = mod;
                } else if (i &amp;lt; 9) {
                    this.modules[8][15 - i - 1 + 1] = mod;
                } else {
                    this.modules[8][15 - i - 1] = mod;
                }
            }

            // fixed module
            this.modules[this.moduleCount - 8][8] = (!test);

        },

        mapData: function(data, maskPattern) {

            var inc = -1;
            var row = this.moduleCount - 1;
            var bitIndex = 7;
            var byteIndex = 0;

            for (var col = this.moduleCount - 1; col &amp;gt; 0; col -= 2) {

                if (col == 6) col--;

                while (true) {

                    for (var c = 0; c &amp;lt; 2; c++) {

                        if (this.modules[row][col - c] == null) {

                            var dark = false;

                            if (byteIndex &amp;lt; data.length) {
                                dark = (((data[byteIndex] &amp;gt;&amp;gt;&amp;gt; bitIndex) &amp;amp; 1) == 1);
                            }

                            var mask = QRUtil.getMask(maskPattern, row, col - c);

                            if (mask) {
                                dark = !dark;
                            }

                            this.modules[row][col - c] = dark;
                            bitIndex--;

                            if (bitIndex == -1) {
                                byteIndex++;
                                bitIndex = 7;
                            }
                        }
                    }

                    row += inc;

                    if (row &amp;lt; 0 || this.moduleCount &amp;lt;= row) {
                        row -= inc;
                        inc = -inc;
                        break;
                    }
                }
            }

        }

    };

    QRCode.PAD0 = 0xEC;
    QRCode.PAD1 = 0x11;

    QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {

        var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);

        var buffer = new QRBitBuffer();

        for (var i = 0; i &amp;lt; dataList.length; i++) {
            var data = dataList[i];
            buffer.put(data.mode, 4);
            buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
            data.write(buffer);
        }

        // calc num max data.
        var totalDataCount = 0;
        for (var i = 0; i &amp;lt; rsBlocks.length; i++) {
            totalDataCount += rsBlocks[i].dataCount;
        }

        if (buffer.getLengthInBits() &amp;gt; totalDataCount * 8) {
            throw new Error("code length overflow. (" +
                buffer.getLengthInBits() +
                "&amp;gt;" +
                totalDataCount * 8 +
                ")");
        }

        // end code
        if (buffer.getLengthInBits() + 4 &amp;lt;= totalDataCount * 8) {
            buffer.put(0, 4);
        }

        // padding
        while (buffer.getLengthInBits() % 8 != 0) {
            buffer.putBit(false);
        }

        // padding
        while (true) {

            if (buffer.getLengthInBits() &amp;gt;= totalDataCount * 8) {
                break;
            }
            buffer.put(QRCode.PAD0, 8);

            if (buffer.getLengthInBits() &amp;gt;= totalDataCount * 8) {
                break;
            }
            buffer.put(QRCode.PAD1, 8);
        }

        return QRCode.createBytes(buffer, rsBlocks);
    }

    QRCode.createBytes = function(buffer, rsBlocks) {

        var offset = 0;

        var maxDcCount = 0;
        var maxEcCount = 0;

        var dcdata = new Array(rsBlocks.length);
        var ecdata = new Array(rsBlocks.length);

        for (var r = 0; r &amp;lt; rsBlocks.length; r++) {

            var dcCount = rsBlocks[r].dataCount;
            var ecCount = rsBlocks[r].totalCount - dcCount;

            maxDcCount = Math.max(maxDcCount, dcCount);
            maxEcCount = Math.max(maxEcCount, ecCount);

            dcdata[r] = new Array(dcCount);

            for (var i = 0; i &amp;lt; dcdata[r].length; i++) {
                dcdata[r][i] = 0xff &amp;amp; buffer.buffer[i + offset];
            }
            offset += dcCount;

            var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
            var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);

            var modPoly = rawPoly.mod(rsPoly);
            ecdata[r] = new Array(rsPoly.getLength() - 1);
            for (var i = 0; i &amp;lt; ecdata[r].length; i++) {
                var modIndex = i + modPoly.getLength() - ecdata[r].length;
                ecdata[r][i] = (modIndex &amp;gt;= 0) ? modPoly.get(modIndex) : 0;
            }

        }

        var totalCodeCount = 0;
        for (var i = 0; i &amp;lt; rsBlocks.length; i++) {
            totalCodeCount += rsBlocks[i].totalCount;
        }

        var data = new Array(totalCodeCount);
        var index = 0;

        for (var i = 0; i &amp;lt; maxDcCount; i++) {
            for (var r = 0; r &amp;lt; rsBlocks.length; r++) {
                if (i &amp;lt; dcdata[r].length) {
                    data[index++] = dcdata[r][i];
                }
            }
        }

        for (var i = 0; i &amp;lt; maxEcCount; i++) {
            for (var r = 0; r &amp;lt; rsBlocks.length; r++) {
                if (i &amp;lt; ecdata[r].length) {
                    data[index++] = ecdata[r][i];
                }
            }
        }

        return data;

    }

    //---------------------------------------------------------------------
    // QRMode
    //---------------------------------------------------------------------

    var QRMode = {
        MODE_NUMBER: 1 &amp;lt;&amp;lt; 0,
        MODE_ALPHA_NUM: 1 &amp;lt;&amp;lt; 1,
        MODE_8BIT_BYTE: 1 &amp;lt;&amp;lt; 2,
        MODE_KANJI: 1 &amp;lt;&amp;lt; 3
    };

    //---------------------------------------------------------------------
    // QRErrorCorrectLevel
    //---------------------------------------------------------------------

    var QRErrorCorrectLevel = {
        L: 1,
        M: 0,
        Q: 3,
        H: 2
    };

    //---------------------------------------------------------------------
    // QRMaskPattern
    //---------------------------------------------------------------------

    var QRMaskPattern = {
        PATTERN000: 0,
        PATTERN001: 1,
        PATTERN010: 2,
        PATTERN011: 3,
        PATTERN100: 4,
        PATTERN101: 5,
        PATTERN110: 6,
        PATTERN111: 7
    };

    //---------------------------------------------------------------------
    // QRUtil
    //---------------------------------------------------------------------

    var QRUtil = {

        PATTERN_POSITION_TABLE: [
            [],
            [6, 18],
            [6, 22],
            [6, 26],
            [6, 30],
            [6, 34],
            [6, 22, 38],
            [6, 24, 42],
            [6, 26, 46],
            [6, 28, 50],
            [6, 30, 54],
            [6, 32, 58],
            [6, 34, 62],
            [6, 26, 46, 66],
            [6, 26, 48, 70],
            [6, 26, 50, 74],
            [6, 30, 54, 78],
            [6, 30, 56, 82],
            [6, 30, 58, 86],
            [6, 34, 62, 90],
            [6, 28, 50, 72, 94],
            [6, 26, 50, 74, 98],
            [6, 30, 54, 78, 102],
            [6, 28, 54, 80, 106],
            [6, 32, 58, 84, 110],
            [6, 30, 58, 86, 114],
            [6, 34, 62, 90, 118],
            [6, 26, 50, 74, 98, 122],
            [6, 30, 54, 78, 102, 126],
            [6, 26, 52, 78, 104, 130],
            [6, 30, 56, 82, 108, 134],
            [6, 34, 60, 86, 112, 138],
            [6, 30, 58, 86, 114, 142],
            [6, 34, 62, 90, 118, 146],
            [6, 30, 54, 78, 102, 126, 150],
            [6, 24, 50, 76, 102, 128, 154],
            [6, 28, 54, 80, 106, 132, 158],
            [6, 32, 58, 84, 110, 136, 162],
            [6, 26, 54, 82, 110, 138, 166],
            [6, 30, 58, 86, 114, 142, 170]
        ],

        G15: (1 &amp;lt;&amp;lt; 10) | (1 &amp;lt;&amp;lt; 8) | (1 &amp;lt;&amp;lt; 5) | (1 &amp;lt;&amp;lt; 4) | (1 &amp;lt;&amp;lt; 2) | (1 &amp;lt;&amp;lt; 1) | (1 &amp;lt;&amp;lt; 0),
        G18: (1 &amp;lt;&amp;lt; 12) | (1 &amp;lt;&amp;lt; 11) | (1 &amp;lt;&amp;lt; 10) | (1 &amp;lt;&amp;lt; 9) | (1 &amp;lt;&amp;lt; 8) | (1 &amp;lt;&amp;lt; 5) | (1 &amp;lt;&amp;lt; 2) | (1 &amp;lt;&amp;lt; 0),
        G15_MASK: (1 &amp;lt;&amp;lt; 14) | (1 &amp;lt;&amp;lt; 12) | (1 &amp;lt;&amp;lt; 10) | (1 &amp;lt;&amp;lt; 4) | (1 &amp;lt;&amp;lt; 1),

        getBCHTypeInfo: function(data) {
            var d = data &amp;lt;&amp;lt; 10;
            while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) &amp;gt;= 0) {
                d ^= (QRUtil.G15 &amp;lt;&amp;lt; (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
            }
            return ((data &amp;lt;&amp;lt; 10) | d) ^ QRUtil.G15_MASK;
        },

        getBCHTypeNumber: function(data) {
            var d = data &amp;lt;&amp;lt; 12;
            while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) &amp;gt;= 0) {
                d ^= (QRUtil.G18 &amp;lt;&amp;lt; (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
            }
            return (data &amp;lt;&amp;lt; 12) | d;
        },

        getBCHDigit: function(data) {

            var digit = 0;

            while (data != 0) {
                digit++;
                data &amp;gt;&amp;gt;&amp;gt;= 1;
            }

            return digit;
        },

        getPatternPosition: function(typeNumber) {
            return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
        },

        getMask: function(maskPattern, i, j) {

            switch (maskPattern) {

                case QRMaskPattern.PATTERN000:
                    return (i + j) % 2 == 0;
                case QRMaskPattern.PATTERN001:
                    return i % 2 == 0;
                case QRMaskPattern.PATTERN010:
                    return j % 3 == 0;
                case QRMaskPattern.PATTERN011:
                    return (i + j) % 3 == 0;
                case QRMaskPattern.PATTERN100:
                    return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
                case QRMaskPattern.PATTERN101:
                    return (i * j) % 2 + (i * j) % 3 == 0;
                case QRMaskPattern.PATTERN110:
                    return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
                case QRMaskPattern.PATTERN111:
                    return ((i * j) % 3 + (i + j) % 2) % 2 == 0;

                default:
                    throw new Error("bad maskPattern:" + maskPattern);
            }
        },

        getErrorCorrectPolynomial: function(errorCorrectLength) {

            var a = new QRPolynomial([1], 0);

            for (var i = 0; i &amp;lt; errorCorrectLength; i++) {
                a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
            }

            return a;
        },

        getLengthInBits: function(mode, type) {

            if (1 &amp;lt;= type &amp;amp;&amp;amp; type &amp;lt; 10) {

                // 1 - 9

                switch (mode) {
                    case QRMode.MODE_NUMBER:
                        return 10;
                    case QRMode.MODE_ALPHA_NUM:
                        return 9;
                    case QRMode.MODE_8BIT_BYTE:
                        return 8;
                    case QRMode.MODE_KANJI:
                        return 8;
                    default:
                        throw new Error("mode:" + mode);
                }

            } else if (type &amp;lt; 27) {

                // 10 - 26

                switch (mode) {
                    case QRMode.MODE_NUMBER:
                        return 12;
                    case QRMode.MODE_ALPHA_NUM:
                        return 11;
                    case QRMode.MODE_8BIT_BYTE:
                        return 16;
                    case QRMode.MODE_KANJI:
                        return 10;
                    default:
                        throw new Error("mode:" + mode);
                }

            } else if (type &amp;lt; 41) {

                // 27 - 40

                switch (mode) {
                    case QRMode.MODE_NUMBER:
                        return 14;
                    case QRMode.MODE_ALPHA_NUM:
                        return 13;
                    case QRMode.MODE_8BIT_BYTE:
                        return 16;
                    case QRMode.MODE_KANJI:
                        return 12;
                    default:
                        throw new Error("mode:" + mode);
                }

            } else {
                throw new Error("type:" + type);
            }
        },

        getLostPoint: function(qrCode) {

            var moduleCount = qrCode.getModuleCount();

            var lostPoint = 0;

            // LEVEL1

            for (var row = 0; row &amp;lt; moduleCount; row++) {

                for (var col = 0; col &amp;lt; moduleCount; col++) {

                    var sameCount = 0;
                    var dark = qrCode.isDark(row, col);

                    for (var r = -1; r &amp;lt;= 1; r++) {

                        if (row + r &amp;lt; 0 || moduleCount &amp;lt;= row + r) {
                            continue;
                        }

                        for (var c = -1; c &amp;lt;= 1; c++) {

                            if (col + c &amp;lt; 0 || moduleCount &amp;lt;= col + c) {
                                continue;
                            }

                            if (r == 0 &amp;amp;&amp;amp; c == 0) {
                                continue;
                            }

                            if (dark == qrCode.isDark(row + r, col + c)) {
                                sameCount++;
                            }
                        }
                    }

                    if (sameCount &amp;gt; 5) {
                        lostPoint += (3 + sameCount - 5);
                    }
                }
            }

            // LEVEL2

            for (var row = 0; row &amp;lt; moduleCount - 1; row++) {
                for (var col = 0; col &amp;lt; moduleCount - 1; col++) {
                    var count = 0;
                    if (qrCode.isDark(row, col)) count++;
                    if (qrCode.isDark(row + 1, col)) count++;
                    if (qrCode.isDark(row, col + 1)) count++;
                    if (qrCode.isDark(row + 1, col + 1)) count++;
                    if (count == 0 || count == 4) {
                        lostPoint += 3;
                    }
                }
            }

            // LEVEL3

            for (var row = 0; row &amp;lt; moduleCount; row++) {
                for (var col = 0; col &amp;lt; moduleCount - 6; col++) {
                    if (qrCode.isDark(row, col) &amp;amp;&amp;amp;
                        !qrCode.isDark(row, col + 1) &amp;amp;&amp;amp;
                        qrCode.isDark(row, col + 2) &amp;amp;&amp;amp;
                        qrCode.isDark(row, col + 3) &amp;amp;&amp;amp;
                        qrCode.isDark(row, col + 4) &amp;amp;&amp;amp;
                        !qrCode.isDark(row, col + 5) &amp;amp;&amp;amp;
                        qrCode.isDark(row, col + 6)) {
                        lostPoint += 40;
                    }
                }
            }

            for (var col = 0; col &amp;lt; moduleCount; col++) {
                for (var row = 0; row &amp;lt; moduleCount - 6; row++) {
                    if (qrCode.isDark(row, col) &amp;amp;&amp;amp;
                        !qrCode.isDark(row + 1, col) &amp;amp;&amp;amp;
                        qrCode.isDark(row + 2, col) &amp;amp;&amp;amp;
                        qrCode.isDark(row + 3, col) &amp;amp;&amp;amp;
                        qrCode.isDark(row + 4, col) &amp;amp;&amp;amp;
                        !qrCode.isDark(row + 5, col) &amp;amp;&amp;amp;
                        qrCode.isDark(row + 6, col)) {
                        lostPoint += 40;
                    }
                }
            }

            // LEVEL4

            var darkCount = 0;

            for (var col = 0; col &amp;lt; moduleCount; col++) {
                for (var row = 0; row &amp;lt; moduleCount; row++) {
                    if (qrCode.isDark(row, col)) {
                        darkCount++;
                    }
                }
            }

            var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
            lostPoint += ratio * 10;

            return lostPoint;
        }

    };


    //---------------------------------------------------------------------
    // QRMath
    //---------------------------------------------------------------------

    var QRMath = {

        glog: function(n) {

            if (n &amp;lt; 1) {
                throw new Error("glog(" + n + ")");
            }

            return QRMath.LOG_TABLE[n];
        },

        gexp: function(n) {

            while (n &amp;lt; 0) {
                n += 255;
            }

            while (n &amp;gt;= 256) {
                n -= 255;
            }

            return QRMath.EXP_TABLE[n];
        },

        EXP_TABLE: new Array(256),

        LOG_TABLE: new Array(256)

    };

    for (var i = 0; i &amp;lt; 8; i++) {
        QRMath.EXP_TABLE[i] = 1 &amp;lt;&amp;lt; i;
    }
    for (var i = 8; i &amp;lt; 256; i++) {
        QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^
            QRMath.EXP_TABLE[i - 5] ^
            QRMath.EXP_TABLE[i - 6] ^
            QRMath.EXP_TABLE[i - 8];
    }
    for (var i = 0; i &amp;lt; 255; i++) {
        QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
    }

    //---------------------------------------------------------------------
    // QRPolynomial
    //---------------------------------------------------------------------

    function QRPolynomial(num, shift) {

        if (num.length == undefined) {
            throw new Error(num.length + "/" + shift);
        }

        var offset = 0;

        while (offset &amp;lt; num.length &amp;amp;&amp;amp; num[offset] == 0) {
            offset++;
        }

        this.num = new Array(num.length - offset + shift);
        for (var i = 0; i &amp;lt; num.length - offset; i++) {
            this.num[i] = num[i + offset];
        }
    }

    QRPolynomial.prototype = {

        get: function(index) {
            return this.num[index];
        },

        getLength: function() {
            return this.num.length;
        },

        multiply: function(e) {

            var num = new Array(this.getLength() + e.getLength() - 1);

            for (var i = 0; i &amp;lt; this.getLength(); i++) {
                for (var j = 0; j &amp;lt; e.getLength(); j++) {
                    num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
                }
            }

            return new QRPolynomial(num, 0);
        },

        mod: function(e) {

            if (this.getLength() - e.getLength() &amp;lt; 0) {
                return this;
            }

            var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));

            var num = new Array(this.getLength());

            for (var i = 0; i &amp;lt; this.getLength(); i++) {
                num[i] = this.get(i);
            }

            for (var i = 0; i &amp;lt; e.getLength(); i++) {
                num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
            }

            // recursive call
            return new QRPolynomial(num, 0).mod(e);
        }
    };

    //---------------------------------------------------------------------
    // QRRSBlock
    //---------------------------------------------------------------------

    function QRRSBlock(totalCount, dataCount) {
        this.totalCount = totalCount;
        this.dataCount = dataCount;
    }

    QRRSBlock.RS_BLOCK_TABLE = [

        // L
        // M
        // Q
        // H

        // 1
        [1, 26, 19],
        [1, 26, 16],
        [1, 26, 13],
        [1, 26, 9],

        // 2
        [1, 44, 34],
        [1, 44, 28],
        [1, 44, 22],
        [1, 44, 16],

        // 3
        [1, 70, 55],
        [1, 70, 44],
        [2, 35, 17],
        [2, 35, 13],

        // 4        
        [1, 100, 80],
        [2, 50, 32],
        [2, 50, 24],
        [4, 25, 9],

        // 5
        [1, 134, 108],
        [2, 67, 43],
        [2, 33, 15, 2, 34, 16],
        [2, 33, 11, 2, 34, 12],

        // 6
        [2, 86, 68],
        [4, 43, 27],
        [4, 43, 19],
        [4, 43, 15],

        // 7        
        [2, 98, 78],
        [4, 49, 31],
        [2, 32, 14, 4, 33, 15],
        [4, 39, 13, 1, 40, 14],

        // 8
        [2, 121, 97],
        [2, 60, 38, 2, 61, 39],
        [4, 40, 18, 2, 41, 19],
        [4, 40, 14, 2, 41, 15],

        // 9
        [2, 146, 116],
        [3, 58, 36, 2, 59, 37],
        [4, 36, 16, 4, 37, 17],
        [4, 36, 12, 4, 37, 13],

        // 10       
        [2, 86, 68, 2, 87, 69],
        [4, 69, 43, 1, 70, 44],
        [6, 43, 19, 2, 44, 20],
        [6, 43, 15, 2, 44, 16],

        // 11
        [4, 101, 81],
        [1, 80, 50, 4, 81, 51],
        [4, 50, 22, 4, 51, 23],
        [3, 36, 12, 8, 37, 13],

        // 12
        [2, 116, 92, 2, 117, 93],
        [6, 58, 36, 2, 59, 37],
        [4, 46, 20, 6, 47, 21],
        [7, 42, 14, 4, 43, 15],

        // 13
        [4, 133, 107],
        [8, 59, 37, 1, 60, 38],
        [8, 44, 20, 4, 45, 21],
        [12, 33, 11, 4, 34, 12],

        // 14
        [3, 145, 115, 1, 146, 116],
        [4, 64, 40, 5, 65, 41],
        [11, 36, 16, 5, 37, 17],
        [11, 36, 12, 5, 37, 13],

        // 15
        [5, 109, 87, 1, 110, 88],
        [5, 65, 41, 5, 66, 42],
        [5, 54, 24, 7, 55, 25],
        [11, 36, 12],

        // 16
        [5, 122, 98, 1, 123, 99],
        [7, 73, 45, 3, 74, 46],
        [15, 43, 19, 2, 44, 20],
        [3, 45, 15, 13, 46, 16],

        // 17
        [1, 135, 107, 5, 136, 108],
        [10, 74, 46, 1, 75, 47],
        [1, 50, 22, 15, 51, 23],
        [2, 42, 14, 17, 43, 15],

        // 18
        [5, 150, 120, 1, 151, 121],
        [9, 69, 43, 4, 70, 44],
        [17, 50, 22, 1, 51, 23],
        [2, 42, 14, 19, 43, 15],

        // 19
        [3, 141, 113, 4, 142, 114],
        [3, 70, 44, 11, 71, 45],
        [17, 47, 21, 4, 48, 22],
        [9, 39, 13, 16, 40, 14],

        // 20
        [3, 135, 107, 5, 136, 108],
        [3, 67, 41, 13, 68, 42],
        [15, 54, 24, 5, 55, 25],
        [15, 43, 15, 10, 44, 16],

        // 21
        [4, 144, 116, 4, 145, 117],
        [17, 68, 42],
        [17, 50, 22, 6, 51, 23],
        [19, 46, 16, 6, 47, 17],

        // 22
        [2, 139, 111, 7, 140, 112],
        [17, 74, 46],
        [7, 54, 24, 16, 55, 25],
        [34, 37, 13],

        // 23
        [4, 151, 121, 5, 152, 122],
        [4, 75, 47, 14, 76, 48],
        [11, 54, 24, 14, 55, 25],
        [16, 45, 15, 14, 46, 16],

        // 24
        [6, 147, 117, 4, 148, 118],
        [6, 73, 45, 14, 74, 46],
        [11, 54, 24, 16, 55, 25],
        [30, 46, 16, 2, 47, 17],

        // 25
        [8, 132, 106, 4, 133, 107],
        [8, 75, 47, 13, 76, 48],
        [7, 54, 24, 22, 55, 25],
        [22, 45, 15, 13, 46, 16],

        // 26
        [10, 142, 114, 2, 143, 115],
        [19, 74, 46, 4, 75, 47],
        [28, 50, 22, 6, 51, 23],
        [33, 46, 16, 4, 47, 17],

        // 27
        [8, 152, 122, 4, 153, 123],
        [22, 73, 45, 3, 74, 46],
        [8, 53, 23, 26, 54, 24],
        [12, 45, 15, 28, 46, 16],

        // 28
        [3, 147, 117, 10, 148, 118],
        [3, 73, 45, 23, 74, 46],
        [4, 54, 24, 31, 55, 25],
        [11, 45, 15, 31, 46, 16],

        // 29
        [7, 146, 116, 7, 147, 117],
        [21, 73, 45, 7, 74, 46],
        [1, 53, 23, 37, 54, 24],
        [19, 45, 15, 26, 46, 16],

        // 30
        [5, 145, 115, 10, 146, 116],
        [19, 75, 47, 10, 76, 48],
        [15, 54, 24, 25, 55, 25],
        [23, 45, 15, 25, 46, 16],

        // 31
        [13, 145, 115, 3, 146, 116],
        [2, 74, 46, 29, 75, 47],
        [42, 54, 24, 1, 55, 25],
        [23, 45, 15, 28, 46, 16],

        // 32
        [17, 145, 115],
        [10, 74, 46, 23, 75, 47],
        [10, 54, 24, 35, 55, 25],
        [19, 45, 15, 35, 46, 16],

        // 33
        [17, 145, 115, 1, 146, 116],
        [14, 74, 46, 21, 75, 47],
        [29, 54, 24, 19, 55, 25],
        [11, 45, 15, 46, 46, 16],

        // 34
        [13, 145, 115, 6, 146, 116],
        [14, 74, 46, 23, 75, 47],
        [44, 54, 24, 7, 55, 25],
        [59, 46, 16, 1, 47, 17],

        // 35
        [12, 151, 121, 7, 152, 122],
        [12, 75, 47, 26, 76, 48],
        [39, 54, 24, 14, 55, 25],
        [22, 45, 15, 41, 46, 16],

        // 36
        [6, 151, 121, 14, 152, 122],
        [6, 75, 47, 34, 76, 48],
        [46, 54, 24, 10, 55, 25],
        [2, 45, 15, 64, 46, 16],

        // 37
        [17, 152, 122, 4, 153, 123],
        [29, 74, 46, 14, 75, 47],
        [49, 54, 24, 10, 55, 25],
        [24, 45, 15, 46, 46, 16],

        // 38
        [4, 152, 122, 18, 153, 123],
        [13, 74, 46, 32, 75, 47],
        [48, 54, 24, 14, 55, 25],
        [42, 45, 15, 32, 46, 16],

        // 39
        [20, 147, 117, 4, 148, 118],
        [40, 75, 47, 7, 76, 48],
        [43, 54, 24, 22, 55, 25],
        [10, 45, 15, 67, 46, 16],

        // 40
        [19, 148, 118, 6, 149, 119],
        [18, 75, 47, 31, 76, 48],
        [34, 54, 24, 34, 55, 25],
        [20, 45, 15, 61, 46, 16]
    ];

    QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {

        var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);

        if (rsBlock == undefined) {
            throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
        }

        var length = rsBlock.length / 3;

        var list = new Array();

        for (var i = 0; i &amp;lt; length; i++) {

            var count = rsBlock[i * 3 + 0];
            var totalCount = rsBlock[i * 3 + 1];
            var dataCount = rsBlock[i * 3 + 2];

            for (var j = 0; j &amp;lt; count; j++) {
                list.push(new QRRSBlock(totalCount, dataCount));
            }
        }

        return list;
    }

    QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {

        switch (errorCorrectLevel) {
            case QRErrorCorrectLevel.L:
                return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
            case QRErrorCorrectLevel.M:
                return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
            case QRErrorCorrectLevel.Q:
                return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
            case QRErrorCorrectLevel.H:
                return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
            default:
                return undefined;
        }
    }

    //---------------------------------------------------------------------
    // QRBitBuffer
    //---------------------------------------------------------------------

    function QRBitBuffer() {
        this.buffer = new Array();
        this.length = 0;
    }

    QRBitBuffer.prototype = {

        get: function(index) {
            var bufIndex = Math.floor(index / 8);
            return ((this.buffer[bufIndex] &amp;gt;&amp;gt;&amp;gt; (7 - index % 8)) &amp;amp; 1) == 1;
        },

        put: function(num, length) {
            for (var i = 0; i &amp;lt; length; i++) {
                this.putBit(((num &amp;gt;&amp;gt;&amp;gt; (length - i - 1)) &amp;amp; 1) == 1);
            }
        },

        getLengthInBits: function() {
            return this.length;
        },

        putBit: function(bit) {

            var bufIndex = Math.floor(this.length / 8);
            if (this.buffer.length &amp;lt;= bufIndex) {
                this.buffer.push(0);
            }

            if (bit) {
                this.buffer[bufIndex] |= (0x80 &amp;gt;&amp;gt;&amp;gt; (this.length % 8));
            }

            this.length++;
        }
    };

    //---------------------------------------------------------------------
    // Support Chinese
    //---------------------------------------------------------------------
    function utf16To8(text) {
        var result = '';
        var c;
        for (var i = 0; i &amp;lt; text.length; i++) {
            c = text.charCodeAt(i);
            if (c &amp;gt;= 0x0001 &amp;amp;&amp;amp; c &amp;lt;= 0x007F) {
                result += text.charAt(i);
            } else if (c &amp;gt; 0x07FF) {
                result += String.fromCharCode(0xE0 | c &amp;gt;&amp;gt; 12 &amp;amp; 0x0F);
                result += String.fromCharCode(0x80 | c &amp;gt;&amp;gt; 6 &amp;amp; 0x3F);
                result += String.fromCharCode(0x80 | c &amp;gt;&amp;gt; 0 &amp;amp; 0x3F);
            } else {
                result += String.fromCharCode(0xC0 | c &amp;gt;&amp;gt; 6 &amp;amp; 0x1F);
                result += String.fromCharCode(0x80 | c &amp;gt;&amp;gt; 0 &amp;amp; 0x3F);
            }
        }
        return result;
    }

    uQRCode = {

        errorCorrectLevel: QRErrorCorrectLevel,

        defaults: {
            size: 354,
            margin: 0,
            backgroundColor: '#ffffff',
            foregroundColor: '#000000',
            fileType: 'png', // 'jpg', 'png'
            errorCorrectLevel: QRErrorCorrectLevel.H,
            typeNumber: -1
        },

        make: function(options) {
            return new Promise((reslove, reject) =&amp;gt; {
                var defaultOptions = {
                    canvasId: options.canvasId,
                    componentInstance: options.componentInstance,
                    text: options.text,
                    size: this.defaults.size,
                    margin: this.defaults.margin,
                    backgroundColor: this.defaults.backgroundColor,
                    foregroundColor: this.defaults.foregroundColor,
                    fileType: this.defaults.fileType,
                    errorCorrectLevel: this.defaults.errorCorrectLevel,
                    typeNumber: this.defaults.typeNumber
                };
                if (options) {
                    for (var i in options) {
                        defaultOptions[i] = options[i];
                    }
                }
                options = defaultOptions;
                if (!options.canvasId) {
                    console.error('uQRCode: Please set canvasId!');
                    return;
                }

                function createCanvas() {
                    var qrcode = new QRCode(options.typeNumber, options.errorCorrectLevel);
                    qrcode.addData(utf16To8(options.text));
                    qrcode.make();

                    var ctx = uni.createCanvasContext(options.canvasId, options.componentInstance);
                    ctx.setFillStyle(options.backgroundColor);
                    ctx.fillRect(0, 0, options.size, options.size);

                    var tileW = (options.size - options.margin * 2) / qrcode.getModuleCount();
                    var tileH = tileW;

                    for (var row = 0; row &amp;lt; qrcode.getModuleCount(); row++) {
                        for (var col = 0; col &amp;lt; qrcode.getModuleCount(); col++) {
                            var style = qrcode.isDark(row, col) ? options.foregroundColor : options.backgroundColor;
                            ctx.setFillStyle(style);
                            var x = Math.round(col * tileW) + options.margin;
                            var y = Math.round(row * tileH) + options.margin;
                            var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
                            var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
                            ctx.fillRect(x, y, w, h);
                        }
                    }

                    setTimeout(function() {
                        ctx.draw(false, (function() {
                            setTimeout(function() {
                                uni.canvasToTempFilePath({
                                    canvasId: options.canvasId,
                                    fileType: options.fileType,
                                    width: options.size,
                                    height: options.size,
                                    destWidth: options.size,
                                    destHeight: options.size,
                                    success: function(res) {
                                        let resData; // 将统一为base64格式
                                        let tempFilePath = res.tempFilePath; // H5为base64，其他为相对路径

                                        // #ifdef H5
                                        resData = tempFilePath;
                                        options.success &amp;amp;&amp;amp; options.success(resData);
                                        reslove(resData);
                                        // #endif

                                        // #ifdef APP-PLUS
                                        const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
                                        let fileReader = new plus.io.FileReader();
                                        fileReader.readAsDataURL(path);
                                        fileReader.onloadend = res =&amp;gt; {
                                            resData = res.target.result;
                                            options.success &amp;amp;&amp;amp; options.success(resData);
                                            reslove(resData);
                                        };
                                        // #endif

                                        // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
                                        uni.getFileSystemManager().readFile({
                                            filePath: tempFilePath,
                                            encoding: 'base64',
                                            success: res =&amp;gt; {
                                                resData = 'data:image/png;base64,' + res.data;
                                                options.success &amp;amp;&amp;amp; options.success(resData);
                                                reslove(resData);
                                            }
                                        })
                                        // #endif

                                        // #ifndef H5 || APP-PLUS || MP-WEIXIN || MP-QQ || MP-TOUTIAO
                                        if (plus) {
                                            const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
                                            let fileReader = new plus.io.FileReader();
                                            fileReader.readAsDataURL(path);
                                            fileReader.onloadend = res =&amp;gt; {
                                                resData = res.target.result;
                                                options.success &amp;amp;&amp;amp; options.success(resData);
                                                reslove(resData);
                                            };
                                        } else {
                                            uni.request({
                                                url: tempFilePath,
                                                method: 'GET',
                                                responseType: 'arraybuffer',
                                                success: res =&amp;gt; {
                                                    resData = `data:image/png;base64,${uni.arrayBufferToBase64(res.data)}`; // 把arraybuffer转成base64
                                                    options.success &amp;amp;&amp;amp; options.success(resData);
                                                    reslove(resData);
                                                }
                                            })
                                        }
                                        // #endif
                                    },
                                    fail: function(error) {
                                        options.fail &amp;amp;&amp;amp; options.fail(error);
                                        reject(error);
                                    },
                                    complete: function(res) {
                                        options.complete &amp;amp;&amp;amp; options.complete(res);
                                    }
                                }, options.componentInstance);
                            }, options.text.length + 100);
                        })());
                    }, 150);
                }

                createCanvas();
            });
        }
    }

})()

export default uQRCode





&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>tp5获取网站的域名host带http</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Wed, 19 Nov 2025 05:47:18 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/tp5huo-qu-wang-zhan-de-yu-ming-hostdai-http-2m25</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/tp5huo-qu-wang-zhan-de-yu-ming-hostdai-http-2m25</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$http = (isHTTPS() == true ? "https://" : "http://") . $_SERVER['HTTP_HOST'];
//获得   https://www.mantools.top

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>PHP发送get和post请求</title>
      <dc:creator>CHENG QIAN</dc:creator>
      <pubDate>Wed, 19 Nov 2025 05:43:58 +0000</pubDate>
      <link>https://forem.com/cheng_qian_8382fdc61158ce/phpfa-song-gethe-postqing-qiu-2kae</link>
      <guid>https://forem.com/cheng_qian_8382fdc61158ce/phpfa-song-gethe-postqing-qiu-2kae</guid>
      <description>&lt;p&gt;PHP发送GET请求，用file_get_contents()&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php 
    $url='https://www.mantools.top/'; 
    $html = file_get_contents($url);
    echo $html; 
?&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PHP发送POST请求，用file_get_contents()&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * 发送post请求
 * @param string $url 请求地址
 * @param array $post_data post键值对数据
 * @return string
 */
function send_post($url, $post_data) {

  $postdata = http_build_query($post_data);
  $options = array(
    'http' =&amp;gt; array(
      'method' =&amp;gt; 'POST',
      'header' =&amp;gt; 'Content-type:application/x-www-form-urlencoded',
      'content' =&amp;gt; $postdata,
      'timeout' =&amp;gt; 15 * 60 // 超时时间（单位:s）
    )
  );
  $context = stream_context_create($options);
  $result = file_get_contents($url, false, $context);

  return $result;
}

//使用方法
$post_data = array(
  'username' =&amp;gt; 'stclair2201',
  'password' =&amp;gt; 'handan'
);
send_post('http://www.mantools.top', $post_data);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
