<?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>DEV Community: vic</title>
    <description>The latest articles on DEV Community by vic (@lizhichao).</description>
    <link>https://dev.to/lizhichao</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%2F633793%2Fc26fa075-f154-47c8-b177-f266ec794a9d.jpeg</url>
      <title>DEV Community: vic</title>
      <link>https://dev.to/lizhichao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lizhichao"/>
    <language>en</language>
    <item>
      <title>An Online Gantt Chart Generator</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Thu, 24 Apr 2025 02:59:29 +0000</pubDate>
      <link>https://dev.to/lizhichao/an-online-gantt-chart-generator-2m37</link>
      <guid>https://dev.to/lizhichao/an-online-gantt-chart-generator-2m37</guid>
      <description>&lt;p&gt;Go to &lt;a href="https://gantt-online.com/" rel="noopener noreferrer"&gt;https://gantt-online.com/&lt;/a&gt; and click the &lt;code&gt;Create Gantt chart&lt;/code&gt; button. You can directly edit or add tasks by clicking on the task name (press Enter to add a task), and then click the "Save" button in the top right corner. The URL in your browser will now display the unique hash address for this Gantt chart, allowing you to open this link and continue editing later.&lt;/p&gt;

&lt;p&gt;For example: &lt;code&gt;https://gantt-online.com/gatt/5a961c12eee956135f961c4e88&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Click the  &lt;code&gt;Share&lt;/code&gt; tool in the top right corner to get the SVG format online link of the Gantt chart.&lt;/p&gt;

&lt;p&gt;For example : &lt;code&gt;https://gantt-online.com/api/svg/5a961c12eee956135f961c4e88/?lang=en&amp;amp;zone=8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The SVG image contains two parameters (which you can modify yourself):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;lang (language):&lt;/strong&gt; &lt;code&gt;en&lt;/code&gt;, &lt;code&gt;zh-cn&lt;/code&gt;, &lt;code&gt;zh-tw&lt;/code&gt;, &lt;code&gt;ja&lt;/code&gt;, &lt;code&gt;ko&lt;/code&gt;, &lt;code&gt;fr&lt;/code&gt;, &lt;code&gt;de&lt;/code&gt;, &lt;code&gt;es&lt;/code&gt;, &lt;code&gt;pt&lt;/code&gt; (9 languages)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;zone (timezone):&lt;/strong&gt; &lt;code&gt;-12&lt;/code&gt; to &lt;code&gt;+12&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since this image is online, the image will automatically refresh with the latest version after you make changes to the Gantt chart. If you reference this image in other documents, it will stay up-to-date in real time, making it perfect for &lt;strong&gt;project planning&lt;/strong&gt; and &lt;strong&gt;progress tracking&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you prefer to download the image, PNG format is also available.&lt;/p&gt;

&lt;p&gt;For larger projects with a longer timeline, you can adjust the date granularity by dragging. The granularity supports three options: &lt;code&gt;day&lt;/code&gt;, &lt;code&gt;week&lt;/code&gt;, and &lt;code&gt;month&lt;/code&gt;.&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%2Fflgd90h77okga172zv4h.jpg" 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%2Fflgd90h77okga172zv4h.jpg" alt="Image description" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The task sidebar can also be adjusted or hidden as needed.&lt;/p&gt;

</description>
      <category>gantt</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Private Deployment Gantt chart Project management tools</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Fri, 15 Mar 2024 01:18:40 +0000</pubDate>
      <link>https://dev.to/lizhichao/private-deployment-gantt-chart-project-management-tools-45lc</link>
      <guid>https://dev.to/lizhichao/private-deployment-gantt-chart-project-management-tools-45lc</guid>
      <description>&lt;h2&gt;
  
  
  Dependent Components
&lt;/h2&gt;

&lt;p&gt;Database &lt;code&gt;mysql&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to download the corresponding installation file from &lt;a href="https://gantt-online.com/deploy"&gt;https://gantt-online.com/deploy&lt;/a&gt; and unzip it&lt;/li&gt;
&lt;li&gt;Enter the unzipped folder in the command line window and modify the configuration content of &lt;code&gt;conf.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute the command &lt;code&gt;./gantt-online -c&lt;/code&gt; to get the client token (root permission is required on Linux)&lt;/li&gt;
&lt;li&gt;Copy the token from Step 3 to create a license authorization code&lt;/li&gt;
&lt;li&gt;Copy the license created in Step 4 and fill it into the configuration file &lt;code&gt;conf.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Initialize the service &lt;code&gt;./gantt-online -i -f conf.yaml&lt;/code&gt; (root permission required on Linux)&lt;/li&gt;
&lt;li&gt;Start the service &lt;code&gt;./gantt-online -f conf.yaml&lt;/code&gt; (root permission required on Linux)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;If on Windows, the command &lt;code&gt;./gantt-online&lt;/code&gt; needs to be changed to &lt;code&gt;gantt-online.exe&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Daemon Process Running Method
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Linux
&lt;/h3&gt;

&lt;p&gt;Recommends Using systemd&lt;br&gt;&lt;br&gt;
Shortcut &lt;code&gt;( ./gantt-online -f conf.yaml &amp;amp;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Recommend using the following method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

Copy code
&lt;span class="c"&gt;#/usr/lib/systemd/system/gantt-online.service &lt;/span&gt;
&lt;span class="c"&gt;#sudo systemctl daemon-reload  &lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;Unit]  
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;zz plan   


&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;simple
&lt;span class="c"&gt;# Fill in the absolute path of your running file and configuration below  &lt;/span&gt;
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/gantt/start &lt;span class="nt"&gt;-f&lt;/span&gt; /home/gantt/conf.yaml  
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always
&lt;span class="nv"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;9  
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;root  
&lt;span class="nv"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; root

&lt;span class="o"&gt;[&lt;/span&gt;Install]  
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enable the service &lt;code&gt;systemctl enable gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start the service &lt;code&gt;systemctl start gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stop the service &lt;code&gt;systemctl stop gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Restart the service &lt;code&gt;systemctl restart gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  mac
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;( ./gantt-online -f conf.yaml &amp;amp;)&lt;/code&gt; or use &lt;code&gt;launchctl&lt;/code&gt; to manage&lt;/p&gt;

&lt;h3&gt;
  
  
  windows
&lt;/h3&gt;

&lt;p&gt;Can use &lt;code&gt;nssm&lt;/code&gt; for service management&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependent Components
&lt;/h2&gt;

&lt;p&gt;Database &lt;code&gt;mysql&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to download the corresponding installation file from &lt;a href="https://gantt-online.com/deploy"&gt;https://gantt-online.com/deploy&lt;/a&gt; and unzip it&lt;/li&gt;
&lt;li&gt;Enter the unzipped folder in the command line window and modify the configuration content of &lt;code&gt;conf.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute the command &lt;code&gt;./gantt-online -c&lt;/code&gt; to get the client token (root permission is required on Linux)&lt;/li&gt;
&lt;li&gt;Copy the token from Step 3 to create a license authorization code&lt;/li&gt;
&lt;li&gt;Copy the license created in Step 4 and fill it into the configuration file &lt;code&gt;conf.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Initialize the service &lt;code&gt;./gantt-online -i -f conf.yaml&lt;/code&gt; (root permission required on Linux)&lt;/li&gt;
&lt;li&gt;Start the service &lt;code&gt;./gantt-online -f conf.yaml&lt;/code&gt; (root permission required on Linux)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;If on Windows, the command &lt;code&gt;./gantt-online&lt;/code&gt; needs to be changed to &lt;code&gt;gantt-online.exe&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Daemon Process Running Method
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Linux
&lt;/h3&gt;

&lt;p&gt;Recommends Using systemd&lt;br&gt;&lt;br&gt;
Shortcut &lt;code&gt;( ./gantt-online -f conf.yaml &amp;amp;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Recommend using the following method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

Copy code
&lt;span class="c"&gt;#/usr/lib/systemd/system/gantt-online.service &lt;/span&gt;
&lt;span class="c"&gt;#sudo systemctl daemon-reload  &lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;Unit]  
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;zz plan   


&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;simple
&lt;span class="c"&gt;# Fill in the absolute path of your running file and configuration below  &lt;/span&gt;
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/gantt/start &lt;span class="nt"&gt;-f&lt;/span&gt; /home/gantt/conf.yaml  
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always
&lt;span class="nv"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;9  
&lt;span class="nv"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;root  
&lt;span class="nv"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; root

&lt;span class="o"&gt;[&lt;/span&gt;Install]  
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enable the service &lt;code&gt;systemctl enable gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start the service &lt;code&gt;systemctl start gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stop the service &lt;code&gt;systemctl stop gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Restart the service &lt;code&gt;systemctl restart gantt-online.service&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  mac
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;( ./gantt-online -f conf.yaml &amp;amp;)&lt;/code&gt; or use &lt;code&gt;launchctl&lt;/code&gt; to manage&lt;/p&gt;

&lt;h3&gt;
  
  
  windows
&lt;/h3&gt;

&lt;p&gt;Can use &lt;code&gt;nssm&lt;/code&gt; for service management&lt;/p&gt;

</description>
      <category>deploy</category>
      <category>gantt</category>
      <category>project</category>
      <category>plan</category>
    </item>
    <item>
      <title>An Excellent Online Gantt Chart Creation Tool</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Thu, 14 Mar 2024 04:44:01 +0000</pubDate>
      <link>https://dev.to/lizhichao/an-excellent-online-gantt-chart-creation-tool-280l</link>
      <guid>https://dev.to/lizhichao/an-excellent-online-gantt-chart-creation-tool-280l</guid>
      <description>&lt;p&gt;An Excellent Online Gantt Chart Creation Tool&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://gantt-online.com/"&gt;gantt-online&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports drag and drop&lt;/li&gt;
&lt;li&gt;Supports task relationships (start-to-start, start-to-finish, finish-to-finish)&lt;/li&gt;
&lt;li&gt;Supports task view and resource view
&lt;/li&gt;
&lt;li&gt;Online sharing&lt;/li&gt;
&lt;li&gt;Supports generating SVG vector images and PNG images&lt;/li&gt;
&lt;li&gt;Supports custom color labels and time settings&lt;/li&gt;
&lt;li&gt;Supports adding task details&lt;/li&gt;
&lt;li&gt;Supports guest mode&lt;/li&gt;
&lt;li&gt;.... Welcome to try it out&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gantt</category>
      <category>project</category>
      <category>management</category>
    </item>
    <item>
      <title>Effortlessly Manage Complex Projects with Our Intuitive Gantt Chart Tool</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Fri, 09 Jun 2023 06:43:29 +0000</pubDate>
      <link>https://dev.to/lizhichao/effortlessly-manage-complex-projects-with-our-intuitive-gantt-chart-tool-2a2c</link>
      <guid>https://dev.to/lizhichao/effortlessly-manage-complex-projects-with-our-intuitive-gantt-chart-tool-2a2c</guid>
      <description>&lt;p&gt;&lt;a href="https://www.gantt-online.com/"&gt;https://www.gantt-online.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gantt Chart | Project Management Tool&lt;br&gt;
Clear at a glance: personnel, tasks, schedule, work hours, cycle, dependencies&lt;br&gt;
Easy management for projects of any size and complexity.&lt;/p&gt;

&lt;p&gt;You can create a Gantt chart without logging in, and once you save it, a unique address will be generated. You can share this address with your team or remember it to continue editing next time without logging in.&lt;/p&gt;

</description>
    </item>
    <item>
      <title> A simple image edge detection method</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Tue, 15 Jun 2021 09:52:30 +0000</pubDate>
      <link>https://dev.to/lizhichao/a-simple-image-edge-detection-method-2cpn</link>
      <guid>https://dev.to/lizhichao/a-simple-image-edge-detection-method-2cpn</guid>
      <description>&lt;h2&gt;
  
  
  A simple image edge detection method
&lt;/h2&gt;

&lt;p&gt;General steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Zoom pictures to improve efficiency&lt;/li&gt;
&lt;li&gt;Picture grayscale&lt;/li&gt;
&lt;li&gt;Calculate edges based on brightness&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The third step is the most critical. There are many ways to directly contrast the adjacent brightness.&lt;/p&gt;

&lt;p&gt;Instructions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require lizhichao/one-img

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;$img_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1.jpg'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; new &lt;span class="se"&gt;\O&lt;/span&gt;neImg&lt;span class="se"&gt;\B&lt;/span&gt;order&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$img&lt;/span&gt;-&amp;gt;setImg&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$img_path&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    -&amp;gt;scale&lt;span class="o"&gt;(&lt;/span&gt;300, 300&lt;span class="o"&gt;)&lt;/span&gt;
    -&amp;gt;outline&lt;span class="o"&gt;()&lt;/span&gt;
    -&amp;gt;save&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; //Output to browser

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  effect
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OBGfL7jr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7cd9mezynrzwu3kj2bx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OBGfL7jr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7cd9mezynrzwu3kj2bx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cWmzfi0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pxk7d8y3ifb2kihwxf7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cWmzfi0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pxk7d8y3ifb2kihwxf7s.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code warehouse
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/lizhichao/doImg"&gt;https://github.com/lizhichao/doImg&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My other warehouse welcome star
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lizhichao/one"&gt;A minimalist high-performance php framework that supports swoole | php-fpm &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lizhichao/one-ck"&gt;clickhouse tcp client&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>images</category>
    </item>
    <item>
      <title>A minimalist high-performance php framework  ，can respond to requests within 1ms</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Thu, 20 May 2021 07:33:48 +0000</pubDate>
      <link>https://dev.to/lizhichao/a-minimalist-high-performance-php-framework-can-respond-to-requests-within-1ms-1i7f</link>
      <guid>https://dev.to/lizhichao/a-minimalist-high-performance-php-framework-can-respond-to-requests-within-1ms-1i7f</guid>
      <description>&lt;h2&gt;
  
  
  One - A minimalist high-performance php framework that supports the [swoole | php-fpm] environment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fast - can respond to requests within &lt;code&gt;1ms&lt;/code&gt; even under &lt;code&gt;php-fpm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Simple - let you focus on what you do with &lt;code&gt;one&lt;/code&gt; instead of how to use &lt;code&gt;one&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Flexible - each component is loosely coupled, can be flexibly matched and used, and the method of use is consistent

&lt;ul&gt;
&lt;li&gt;Native sql can be used with model relation &lt;code&gt;with&lt;/code&gt;, relation can cross database types&lt;/li&gt;
&lt;li&gt;session can be used under http, websocket or even tcp, udp and cli&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;High efficiency - operational performance, development efficiency, and easy maintenance.&lt;/li&gt;
&lt;li&gt;Lightweight - no other dependencies, the total code amount of all components from routing and orm does not exceed 500k. If there is no complicated calling relationship in secondary development, you can quickly grasp the design principle&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  hello world
&lt;/h2&gt;

&lt;p&gt;install&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project lizhichao/one-app app
&lt;span class="nb"&gt;cd &lt;/span&gt;app
php App/swoole.php 

&lt;span class="c"&gt;# stop ： `php App/swoole.php -o stop`  &lt;/span&gt;
&lt;span class="c"&gt;# reload ： `php App/swoole.php -o reload`  &lt;/span&gt;
&lt;span class="c"&gt;# Daemon start ： `php App/swoole.php -o start`  &lt;/span&gt;

curl http://127.0.0.1:8081/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  performance
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;reference：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.techempower.com/benchmarks/#section=test&amp;amp;runid=57b25c85-082a-4013-b572-b0939006eaff&amp;amp;hw=ph&amp;amp;test=query&amp;amp;d=dz&amp;amp;a=2&amp;amp;o=e"&gt;test1 (mysql + orm)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/the-benchmarker/web-frameworks"&gt;test2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Main components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Router

&lt;ul&gt;
&lt;li&gt;Support greedy matching and priority&lt;/li&gt;
&lt;li&gt;Support ws/tcp/http……any protocol&lt;/li&gt;
&lt;li&gt;Good performance, adding tens of thousands of routes will not reduce the parsing performance&lt;/li&gt;
&lt;li&gt;Routing grouping, middleware...all there should be&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;ORM

&lt;ul&gt;
&lt;li&gt;Support database: mysql, clickHouse,&lt;/li&gt;
&lt;li&gt;Relation processing: one-to-one, one-to-many, many-to-one, polymorphism... There are various relations, which can be related across database types&lt;/li&gt;
&lt;li&gt;Cache: Automatically refresh data, support configuration of various cache granularities&lt;/li&gt;
&lt;li&gt;Event: All operations can be captured, including you use native SQL to operate the database&lt;/li&gt;
&lt;li&gt;Database connection: synchronous, asynchronous, blocking, disconnection and reconnection are all supported&lt;/li&gt;
&lt;li&gt;sql template: automatically generate template id, you can understand what types of sql the project has, and the proportion of the number of calls, and provide data support for later data optimization.&lt;/li&gt;
&lt;li&gt;Statement reuse: Provide SQL execution performance&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;rpc

&lt;ul&gt;
&lt;li&gt;Can automatically generate remote method mapping, support ide prompt&lt;/li&gt;
&lt;li&gt;Direct call mapping method == call remote method, support chain call&lt;/li&gt;
&lt;li&gt;Support &lt;code&gt;rpc middleware&lt;/code&gt;, authentication, encryption and decryption, caching...&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Log

&lt;ul&gt;
&lt;li&gt;Complete information: record the complete file name + line number to quickly locate the code location&lt;/li&gt;
&lt;li&gt;requestId: You can easily view the entire request log information and service relationship&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Router
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;App\Controllers\IndexController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'@index'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// router with params&lt;/span&gt;
&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/user/{id}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;App\Controllers\IndexController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'@user'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// router with group&lt;/span&gt;
&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'namespace'&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'App\\Test\\WebSocket'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// websocket router&lt;/span&gt;
    &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ws'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'/a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'TestController@abc'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ws'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'/b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'TestController@bbb'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Middleware&lt;/span&gt;
&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'middle'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;App\Test\MixPro\TestMiddle&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'@checkSession'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/mix/ws'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'@ws'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/user/{id}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;App\Controllers\IndexController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'@user'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/mix/http/send'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'@httpSend'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  orm
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Define the model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;One\Database\Mysql\Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// There is no need to specify the primary key in the model, the framework will cache the database structure&lt;/span&gt;
&lt;span class="c1"&gt;// Automatically match the primary key, automatically filter the fields in the non-table structure&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Define the table name corresponding to the model&lt;/span&gt;
    &lt;span class="k"&gt;CONST&lt;/span&gt; &lt;span class="no"&gt;TABLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'users'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// define relationship&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'user_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// define event&lt;/span&gt;
    &lt;span class="c1"&gt;// Whether to enable automatic caching&lt;/span&gt;
    &lt;span class="c1"&gt;// ……&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use model
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The database connection is a single column under &lt;code&gt;fpm&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;All database operations are automatically switched to connection pool in &lt;code&gt;swoole&lt;/code&gt; mode
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Query a record&lt;/span&gt;
&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Related query&lt;/span&gt;
&lt;span class="nv"&gt;$user_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;whereIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// update&lt;/span&gt;
&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'aaa'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="c1"&gt;// or&lt;/span&gt;
&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'aaa'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="c1"&gt;// $r To influence the number of records&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cache
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Set cache without expiration time&lt;/span&gt;
&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ccc'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set the cache to expire in 1 minute&lt;/span&gt;
&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ccc'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ccc'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// or cache ccc expires 10s under tag1&lt;/span&gt;
&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ccc'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'info'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="s1"&gt;'tag1'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Refresh all caches under tag1&lt;/span&gt;
&lt;span class="nc"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tag1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Code warehouse&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lizhichao/one"&gt;https://github.com/lizhichao/one&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>phpframework</category>
    </item>
    <item>
      <title>A simple log collector listening log file written to clickhouse</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Wed, 19 May 2021 03:16:06 +0000</pubDate>
      <link>https://dev.to/lizhichao/a-simple-log-collector-listening-log-file-written-to-clickhouse-3kfc</link>
      <guid>https://dev.to/lizhichao/a-simple-log-collector-listening-log-file-written-to-clickhouse-3kfc</guid>
      <description>&lt;p&gt;A simple log collector, Monitor files through tail -F command, write to the Clickhouse. Very low occupancy of resources, It can process more than 100 thousand log information per second&lt;/p&gt;

&lt;h2&gt;
  
  
  install
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;composer require lizhichao/log2ck&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  example
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tail -F apapche/access.log | php apache_log.php -h tcp://127.0.0.1:9000 -u default -p 123456 -d logs -t apache_log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;options : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-h&lt;/code&gt; clickhouse host port&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-u&lt;/code&gt; clickhouse user name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; clickhouse password&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; clickhouse database name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; clickhouse table name&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  principle
&lt;/h2&gt;

&lt;p&gt;Use clickhouse to support streaming writing&lt;/p&gt;

&lt;p&gt;Code factory library used&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lizhichao/log2ck"&gt;https://github.com/lizhichao/log2ck&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lizhichao/one-ck"&gt;https://github.com/lizhichao/one-ck&lt;/a&gt;&lt;/p&gt;

</description>
      <category>clickhouse</category>
      <category>php</category>
    </item>
    <item>
      <title>A simple parameter validator</title>
      <dc:creator>vic</dc:creator>
      <pubDate>Wed, 19 May 2021 02:22:44 +0000</pubDate>
      <link>https://dev.to/lizhichao/a-simple-parameter-validator-1j3n</link>
      <guid>https://dev.to/lizhichao/a-simple-parameter-validator-1j3n</guid>
      <description>&lt;p&gt;A simple parameter validator&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'xxxx'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'age'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nv"&gt;$vt&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Validator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$vt&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|min_len:5|max_len:10'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// required 5&amp;lt;= strlen(name) &amp;lt;=10&lt;/span&gt;
    &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// required email&lt;/span&gt;
    &lt;span class="s1"&gt;'age'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'uint|min:18|max:200'&lt;/span&gt;  &lt;span class="c1"&gt;// options Positive integer 18&amp;lt;= age &amp;lt;=200&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isOk&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;print_r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$vt&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getErrs&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;//Array&lt;/span&gt;
&lt;span class="c1"&gt;//(&lt;/span&gt;
&lt;span class="c1"&gt;//    [0] =&amp;gt; name can not be empty&lt;/span&gt;
&lt;span class="c1"&gt;//    [1] =&amp;gt; email incorrect format&lt;/span&gt;
&lt;span class="c1"&gt;//    [2] =&amp;gt; age not less than 18&lt;/span&gt;
&lt;span class="c1"&gt;//)&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Built-in rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;required&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;numeric&lt;/code&gt; numbers include floating point numbers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;min&lt;/code&gt; cannot be less than&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max&lt;/code&gt; cannot be greater than&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;min_len&lt;/code&gt; cannot be shorter than&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_len&lt;/code&gt; cannot be longer than&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;int&lt;/code&gt; integer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uint&lt;/code&gt; positive integer &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;email&lt;/code&gt; mailbox format&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ip&lt;/code&gt; ip format&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stop&lt;/code&gt; prevents bubbling (when a rule is not met, the remaining rules are not verified)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  If not enough? Customizable rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$vt&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'between'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'msg'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;':attribute can only be between :arg1-:arg2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'fn'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nv"&gt;$arg1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nv"&gt;$arg2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nv"&gt;$vt&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'a'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'a'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|between:3,10'&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Check whether a value exists in the database&lt;/span&gt;
&lt;span class="nv"&gt;$vt&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'exist'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'msg'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'the :attribute already exists'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'fn'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$filed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$filed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nv"&gt;$vt&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'sss@ss.com'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|exist:users,email'&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can be used here &lt;br&gt;
&lt;a href="https://github.com/lizhichao/one"&gt;https://github.com/lizhichao/one&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
    </item>
  </channel>
</rss>
