shell 创建conf文件,并写入内容(shell创建nginx vhost配置文件)
点赞评论收藏浏览1142023-06-30 14:56:24php HTML解析库用法,PHP玩转HTML(SimpleHtmlDom)
我们在生成静态页中,经常会遇到需要处理html文档,里面需要用到很多节点,插入各种动态数据,修改各种内容。我们首先想到用正则匹配内容然后修改,这样也可以的。今天我们学习一个PHP的HTML解析库,用它来处理html文档。A HTML DOM parser written in PHP - let you manipulate HTML in a very easy way! This is a fork of PHP Simple HTML DOM Parser project but instead of string manipulation we use DOMDocument and modern php classes like "Symfony CssSelector".PHP 7.0+ & 8.0 SupportPHP-FIG StandardComposer & PSR-4 supportPHPUnit testing via Travis CIPHP-Quality testing via SensioLabsInsightUTF-8 Support (more support via "voku/portable-utf8")Invalid HTML Support (partly ...)Find tags on an HTML page with selectors just like jQueryExtract contents from HTML in a single line引入:使用composer下载库composer require voku/simple_html_dom composer require voku/portable-utf8使用:use voku\helper\HtmlDomParser; require_once 'composer/autoload.php'; ... $dom = HtmlDomParser::str_get_html($str); // or $dom = HtmlDomParser::file_get_html($file); $element = $dom->findOne('#css-selector'); // "$element" === instance of "SimpleHtmlDomInterface" $elements = $dom->findMulti('.css-selector'); // "$elements" === instance of SimpleHtmlDomNodeInterface<int, SimpleHtmlDomInterface> $elementOrFalse = $dom->findOneOrFalse('#css-selector'); // "$elementOrFalse" === instance of "SimpleHtmlDomInterface" or false $elementsOrFalse = $dom->findMultiOrFalse('.css-selector'); // "$elementsOrFalse" === instance of SimpleHtmlDomNodeInterface<int, SimpleHtmlDomInterface> or false ...从url中加载html文档从字符串中加载html文档从文件中加载html文档// 新建一个Dom实例 $html = new simple_html_dom(); // 从url中加载 $html->load_file('http://www.alingfeng.cn'); // 从字符串中加载 $html->load('<html><body>从字符串中加载html文档演示</body></html>'); //从文件中加载 $html->load_file('path/file/test.html'); //创建HTML文档 // Create a DOM object from a string $html = str_get_html('<html><body>Hello!</body></html>'); // Create a DOM object from a URL $html = file_get_html('http://www.google.com/'); // Create a DOM object from a HTML file $html = file_get_html('test.htm'); 查找html元素可以使用find函数来查找html文档中的元素。返回的结果是一个包含了对象的数组。我们使用HTML DOM解析类中的函数来访问这些对象,下面给出几个示例://查找html文档中的超链接元素 $a = $html->find('a'); //查找文档中第(N)个超链接,如果没有找到则返回空数组. $a = $html->find('a', 0); // 查找id为main的div元素 $main = $html->find('div[id=main]',0); // 查找所有包含有id属性的div元素 $divs = $html->find('div[id]'); // 查找所有包含有id属性的元素 $divs = $html->find('[id]'); // 查找id='#container'的元素 $ret = $html->find('#container'); // 找到所有class=foo的元素 $ret = $html->find('.foo'); // 查找多个html标签 $ret = $html->find('a, img'); // 还可以这样用 $ret = $html->find('a[title], img[title]'); // 查找 ul列表中所有的li项 $ret = $html->find('ul li'); //查找 ul 列表指定class=selected的li项 $ret = $html->find('ul li.selected'); // 返回父元素 $e->parent; // 返回子元素数组 $e->children; // 通过索引号返回指定子元素 $e->children(0); // 返回第一个资源速 $e->first_child (); // 返回最后一个子元素 $e->last _child (); // 返回上一个相邻元素 $e->prev_sibling (); //返回下一个相邻元素 $e->next_sibling ();元素属性操作使用简单的正则表达式来操作属性选择器。[attribute] – 选择包含某属性的html元素[attribute=value] – 选择所有指定值属性的html元素[attribute!=value]- 选择所有非指定值属性的html元素[attribute^=value] -选择所有指定值开头属性的html元素[attribute$=value] 选择所有指定值结尾属性的html元素[attribute*=value] -选择所有包含指定值属性的html元素// 本例中将$a的锚链接值赋给$link变量 $link = $a->href; $link = $html->find('a',0)->href;每个对象都有4个基本对象属性:tag – 返回html标签名innertext – 返回innerHTMLoutertext – 返回outerHTMLplaintext – 返回html标签中的文本//给$a的锚链接赋新值 $a->href = 'http://www.jb51.net'; // 删除锚链接 $a->href = null; // 检测是否存在锚链接 if(isset($a->href)) { //代码 }解析器中没有专门的方法来添加、删除元素,不过可以变通一下使用:// 封装元素 $e->outertext = '<div class="wrap">' . $e->outertext . '<div>'; // 删除元素 $e->outertext = ''; // 添加元素 $e->outertext = $e->outertext . '<div>foo<div>'; // 插入元素 $e->outertext = '<div>foo<div>' . $e->outertext; $doc = $html; // 输出 echo $doc; //如何避免解析器消耗过多内存 $html->clear();简单示例:$html = file_get_html('http://www.alingfeng.cn/');//获取html $dom = new simple_html_dom(); //new simple_html_dom对象 $dom->load($html) //加载html // Find all images foreach($dom->find('img') as $element) { //获取img标签数组 echo $element->src . '<br>'; //获取每个img标签中的src } // Find all links foreach($dom->find('a') as $element){ //获取a标签的数组 echo $element->href . '<br>';//获取每个a标签中的href } $html = file_get_html('http://slashdot.org/'); //获取html $dom = new simple_html_dom(); //new simple_html_dom对象 $dom->load($html); //加载html // Find all article blocks foreach($dom->find('div.article') as $article) { $item['title'] = $article->find('div.title', 0)->plaintext; //plaintext 获取纯文本 $item['intro'] = $article->find('div.intro', 0)->plaintext; $item['details'] = $article->find('div.details', 0)->plaintext; $articles[] = $item; } print_r($articles); // Create DOM from string $html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>'); $dom = new simple_html_dom(); //new simple_html_dom对象</p><p> $dom->load($html); //加载html $dom->find('div', 1)->class = 'bar'; //class = 赋值 给第二个div的class赋值</p><p> $dom->find('div[id=hello]', 0)->innertext = 'foo'; //innertext内部文本</p><p> echo $dom;find示例:find ( string $selector [, int $index] ) // Find all anchors, returns a array of element objects a标签数组 $ret = $html->find('a');</p><p> // Find (N)th anchor, returns element object or null if not found (zero based)第一个a标签 $ret = $html->find('a', 0);</p><p> // Find lastest anchor, returns element object or null if not found (zero based)最后一个a标签 $ret = $html->find('a', -1); </p><p> // Find all <div> with the id attribute $ret = $html->find('div[id]');</p><p> // Find all <div> which attribute id=foo $ret = $html->find('div[id=foo]'); </p><p> // Find all element which id=foo $ret = $html->find('#foo');</p><p> // Find all element which class=foo $ret = $html->find('.foo');</p><p> // Find all element has attribute id $ret = $html->find('*[id]'); </p><p> // Find all anchors and images a标签与img标签数组 $ret = $html->find('a, img'); </p><p> // Find all anchors and images with the "title" attribute $ret = $html->find('a[title], img[title]');</p><p> // Find all <li> in <ul> $es = $html->find('ul li'); ul标签下的li标签数组</p><p> // Find Nested <div> tags $es = $html->find('div div div'); div标签下div标签下div标签数组</p><p> // Find all <td> in <table> which class=hello $es = $html->find('table.hello td'); table标签下td标签数组</p><p> // Find all td tags with attribite align=center in table tags $es = $html->find(''table td[align=center]'); </p><p> //5.Element //的方法 $e = $html->find("div", 0); //$e 所拥有的方法如下表所示 //Attribute Name Usage $e->tag //标签 $e->outertext //外文本 $e->innertext //内文本 $e->plaintext //纯文本 </p><p> </p><p> // Example $html = str_get_html("<div>foo <b>bar</b></div>"); echo $e->tag; // Returns: " div" echo $e->outertext; // Returns: " <div>foo <b>bar</b></div>" echo $e->innertext; // Returns: " foo <b>bar</b>" echo $e->plaintext; // Returns: " foo bar"</p><p> /6.DOM traversing 方法 //Method Description mixed$e->children ( [int $index] ) //子元素 element$e->parent () //父元素 element$e->first_child () //第一个子元素 element$e->last_child () //最后一个子元素 element$e->next_sibling () //后一个兄弟元素 element$e->prev_sibling () //前一个兄弟元素 </p><p> // Example echo $html->find("#div1", 0)->children(1)->children(1)->children(2)->id; // or echo $html->getElementById("div1")->childNodes(1)->childNodes(1)->childNodes(2)->getAttribute('id');参考链接: https://github.com/voku/simple_html_dom https://blog.csdn.net/qq_36025814/article/details/89500333
查看详情点赞评论1收藏浏览1502023-07-11 11:50:15JS 实现网页复内容复制,携带作者信息
有时候我们站长想用户复制我们的页面内容,携带作者信息。下面是我们的JS实现代码:// 内容复制功能取消 $(function () { var Sys = {}; var ua = navigator.userAgent.toLowerCase(); if (window.ActiveXObject) { document.body.oncopy = function () { event.returnValue = false; var t = document.selection.createRange().text; var s = "-----------------------尊重作者,转载请标明出处:(alingfeng.cn),原文链接:" + location.href; clipboardData.setData("Text", t + "" + s); }; } else { function addLink() { var body_element = document.getElementsByTagName("body")[0]; var selection; selection = window.getSelection(); var pagelink = "-----------------------尊重作者,转载请标明出处:(alingfeng.cn),原文链接:" + location.href; var copytext = selection + pagelink; var newdiv = document.createElement("div"); newdiv.style.position = "absolute"; newdiv.style.left = "-99999px"; body_element.appendChild(newdiv); newdiv.innerHTML = copytext; selection.selectAllChildren(newdiv); window.setTimeout(function () { body_element.removeChild(newdiv); }, 0); } document.oncopy = addLink; } });这样我们复制内容的时候就会携带设置的内容了。
查看详情点赞评论收藏浏览1672024-02-29 13:51:41PHP 利用ZipArchive类库实现压缩&解压文件夹
最近有一个小的功能需求,就是需要通过访问接口根据token访问或下载远程的资源压缩包,所以需要实现资源文件夹的压缩及解压,用了很多库最后发现这个类库是比较方便的。zip文件夹压缩/** * 压缩文件夹 */ public function createZipFile(){ $folderPath = public_path("target"); $zipFilePath = public_path().'/target.zip'; $zip = new ZipArchive(); if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) { // 递归添加文件夹下的所有文件和子文件夹 $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($folderPath), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($files as $name => $file) { if (!$file->isDir()) { $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($folderPath) + 1); $zip->addFile($filePath, $relativePath); } } $zip->close(); echo '文件夹压缩成功'; } else { echo '无法打开或创建压缩文件'; } }解压zip压缩包 /** * 网站html解压 * @param $url * @return string */ public function websiteHtmlHandle($url) { $pathInfo = pathinfo($url); $extension = $pathInfo['extension']; //只允许解压zip格式文件 if (in_array($extension, ["zip"])) { try { $targetFile = $this->downLoadFile($url); $zip = new ZipArchive(); if ($zip->open($targetFile) === TRUE) { $outputFolder = public_path(); if (!is_dir($outputFolder)) { mkdir($outputFolder, 0777, true); } // 解压缩文件,保留原文件结构 $zip->extractTo($outputFolder); $zip->close(); $this->deleteDirectory($targetFile); } else { return $this->error('解压失败!'); // 处理打开压缩文件失败的情况 } } catch (\Exception $e) { return $this->error($e->getMessage()); } }else{ return $this->error('不允许解压改格式压缩包!'); } return $this->success(); }看看操作结果:功能没问题。
查看详情点赞评论收藏浏览1562024-05-14 11:20:37PHP中的HTTP请求(GET请求,POST请求),及response响应返回
不说了,直接记录代码,下次直接用。get请求:/** * GET请求 * @param $url * @return mixed */ public function curlGet($url){ $ch1 = curl_init(); $timeout = 0; curl_setopt($ch1, CURLOPT_URL, $url); curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch1, CURLOPT_ENCODING, ''); curl_setopt($ch1, CURLOPT_MAXREDIRS, 10); curl_setopt($ch1, CURLOPT_HTTPHEADER, array()); curl_setopt($ch1, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch1, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch1, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch1, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); $access_txt = curl_exec($ch1); curl_close($ch1); return json_decode($access_txt, true); }post请求:/** * 发送http post请求 * @param $url * @param $data * @param array $header * @param bool $is_json * @return mixed|string */ function httpPost($url, $data, $header = [],$is_json = true) { if (empty($header)) { $header = array( "Accept: application/json", "Content-Type:application/json;charset=utf-8", ); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); if (curl_errno($ch)) { $error_message = curl_error($ch); @file_put_contents(storage_path('logs/error.log'), var_export($error_message, true) . PHP_EOL, FILE_APPEND); } curl_close($ch); if($is_json){ return json_decode($res, true); } return trim($res); }response响应返回(记录日常用的下次直接用了):/** * 响应 * @param null $msg * @param int $code * @param array $data * @param int $result_code * @param string $type * @return void */ public function response($msg = null,$code = self::SUCCESS,$data = [],$result_code = 200,$type = 'application/json') { $result = [ 'msg' => $msg, 'code' => $code, 'data' => $data, ]; $this->header['Content-Type'] = $type; $response = response($result,$result_code,$this->header); throw new HttpResponseException($response); } /** * @param array $data * @param string $message * @param int $status * @return string */ protected function success($data = [], $message = 'success', $status = 200) { $array = compact('status', 'message', 'data'); return json_encode($array, JSON_UNESCAPED_UNICODE); } /** * @param int $status * @param string $message * @param array $data * @return string */ protected function error($message = 'error', $status = 400, $data = []) { $array = compact('status', 'message', 'data'); return json_encode($array, JSON_UNESCAPED_UNICODE); }
查看详情点赞评论收藏浏览1202024-05-20 12:05:27Gin框架系列教程(11)- gin 集成Redis,简单使用
我们在项目中经常会用到redis缓存数据,gin框架中使用redis非常简单。我们封装一下,我用的是go-redispackage redis_client import ( "context" "time" "github.com/redis/go-redis/v9" ) var redisClient *redis.Client var ctx = context.Background() // 设置reids值 func Set(key string, value string, time time.Duration) error { err := redisClient.Set(ctx, key, value, time).Err() if err != nil { return err } return nil } // 获取reids值 func Get(key string) (string, error) { value, err := redisClient.Get(ctx, key).Result() if err != nil { return "", err } return value, err } // 删除rediskey func Del(key string) error { err := redisClient.Del(ctx, key).Err() if err != nil { return err } return nil } func RedisInit() { client := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", Password: "", DB: 0, }) timeout, goBack := context.WithTimeout(context.Background(), time.Second*3) defer goBack() _, err := client.Ping(timeout).Result() if err != nil { panic("redis初始化失败! " + err.Error()) } redisClient = client } func init() { RedisInit() } 我们调用方法就可以使用了redis_client.Set("lxl", "aaaa", 10*time.Minute) value, _ := redis_client.Get("lxl") fmt.Println(value)我们就可以看到结果:
查看详情点赞评论收藏浏览2702024-05-25 14:35:48云服务器 - 带宽实际下载速度(计算方法)
云服务器吧以1Mbps公网带宽为例,云服务器1M带宽实际下载速度峰值128KB/S,为什么不是1M/S,怎么计算的?这是由于带宽计算单位导致的,云计算厂商提供的公网带宽计算单位使用的是比特(bit),而用户下载速度使用的单位是字节(Byte),8比特(bit) = 1字节(Byte),所以,宽带和下载速度之间有个8倍的关系。N兆带宽和下载速度转换计算公式:N*M bit/s = N*1024K bit/s = N*128KByte/s根据公式计算:1M带宽实际下载速度峰值为:1 * 128KB/S = 128KB/S2M带宽实际下载速度峰值为:2 * 128KB/S = 256KB/S3M带宽实际下载速度峰值为:3 * 128KB/S = 384KB/S4M带宽实际下载速度峰值为:4 * 128KB/S = 512KB/S5M带宽实际下载速度峰值为:5 * 128KB/S = 640KB/S6M带宽实际下载速度峰值为:6 * 128KB/S = 768KB/S7M带宽实际下载速度峰值为:7 * 128KB/S = 896KB/S8M带宽实际下载速度峰值为:8 * 128KB/S = 1M/S9M带宽实际下载速度峰值为:9 * 128KB/S = 1.125M/S10M带宽实际下载速度峰值为:10 * 128KB/S = 1.25M/S20M带宽实际下载速度峰值为:20 * 128KB/S = 2.5M/S30M带宽实际下载速度峰值为:30 * 128KB/S = 3.75M/S50M带宽实际下载速度峰值为:50 * 128KB/S = 6.25M/S100M带宽实际下载速度峰值为:100 * 128KB/S = 12.5M/S200M带宽实际下载速度峰值为:200 * 128KB/S = 25M/SN兆带宽实际下载速度峰值为:N * 128KB/S以此类推…综上,云厂商提供的1Mbps带宽是指bit,而用户下载使用的单位是Byte,1Byte = 8bit,所以云厂商给的云服务器公网带宽除以8就是实际的下载速度,1M带宽下载速度128KB/秒。
查看详情点赞评论收藏浏览1772024-10-25 14:17:23安装宝塔后,连接mysql的root账户
问题:用宝塔安装mysql数据库,本地navicat 连接数据库 root 用户 连接不上原因:宝塔安装的数据库root 用户默认不可以远程连接解决方法:用命令行工具连接到服务器中用命令行的方式连接上数据库,然后修改数据库的mysql 中的user 数据表 把host 列修改为 % 就可以了注:这个权限信息实际上存储在mysql 数据库 里面有一个数据库叫做mysql 数据库里面有一张表叫user user 里面存储的就是各个用户的信息,包括是不是可以远程连接所以修改这个表的root 用的 host 为 % 就可以了, %代表所有 ip 都可以登录这个用户1、登录MySQL数据库mysql -u root -p2、切换mysql数据库use mysql3、修改mysql 数据库user 表的信息update mysql.user set Host = '%' where User = 'root' and Host = 'localhost';4、刷新MySQL缓存//flush privileges; FLUSH PRIVILEGES;这样就可以直接连接到MySQL的root账号了。参考文章: https://blog.csdn.net/qq_38296051/article/details/120784872
查看详情点赞评论收藏浏览3092024-12-03 09:34:58TiDB单机版简易安装和连接访问
tidb的单机简易版安装,方法有好几种。记录一种相对简单的一种,仅供测试。想系统学习的可以用TiUP Playground安装单机版,或者安装集群。1、下载tidbwget http://download.pingcap.org/tidb-latest-linux-amd64.tar.gz2、解压tar -zxvf tidb-latest-linux-amd64.tar.gz3、启动pd,tikv,tidb,(可以直接启动,也可以nohup启动)nohup ./bin/pd-server --data-dir=pd --log-file=pd.log & nohup ./bin/tikv-server --pd="127.0.0.1:2379" --data-dir=tikv --log-file=tikv.log & nohup ./bin/tidb-server --store=tikv --path="127.0.0.1:2379" --log-file=tidb.log &4、命令链接mysql -h 127.0.0.1 -P 4000 -u root 5、简单命令操作show databases; select tidb_version(); select version(); //查询用户 select user,host from mysql.user; //修改root用户密码 ALTER USER 'root'@'%' IDENTIFIED BY 'xxx'; //命令带密码连接 mysql -h 127.0.0.1 -P 4000 -u root -p6、外部工具连接
查看详情点赞评论收藏浏览2512024-12-03 10:01:31