PHP 没有获取当前页面 url 的内置函数,获取当前页面 url 需要几个函数共同协作才行。网址一般由协议(http/https)、主机名(域名)、端口(http 默认是 80,https 默认是 443)、目录、文件、查询参数等构成,我们只要分别获取这几部分然后再组合起来就可以了。
协议
这个可由 $_SERVER['HTTPS']来判断,该值存在即为 https ,否则就是 http 。
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
主机名
该部分比较简单,不需要判断,由$_SERVER['HTTP_HOST']获取
$host=$_SERVER['HTTP_HOST'];
端口
端口可用$_SERVER['SERVER_PORT']来获取
$port=$_SERVER['SERVER_PORT'];
目录、文件、查询参数
这部分用$_SERVER['REQUEST_URI']获取就可以了,包含请求的完整路径和查询字符串
$request=$_SERVER['REQUEST_URI'];
各部分都搞定后,剩下的就是组合起来了,一个完整的 URL 可以表示为:
$curUrl=$protocol.$host.":".$port.$request;
封装成函数
function getCurrentPageURL() {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://"';
$host = $_SERVER['HTTP_HOST'];
$request = $_SERVER['REQUEST_URI'];
return $protocol . $host . $request;
}
一般端口都是默认的,所以在封装函数时没有加端口,如果有需要,自行添加即可。
使用示例
$curURL = getCurrentPageURL();
echo $currentURL;
通过以上方式就可以轻松地获取当前页面的完整 URL,并在需要时使用它了。...
其实我挺喜欢 file_get_contents 的,感觉很轻量,一般的 GET 或者 POST 都能胜任,自用的话,没必要动不动就拿出重量级的 CURL,今天就简单写写在 php 中如何使用 file_get_contents 发送数据。
直接获取网页或文件内容
$url="https://notes.zeng.love";
$result=file_get_contents($url);
echo $result;
发送数据
$posturl="https://notes.zeng.love";
$post_data = array(
'key1' => 'value1',
'key2' => 'value2'
);
$postdata = http_build_query($post_data);
$options = array(
'http' => array(
'method' => 'POST',//发送方式,post或get
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $postdata,
'timeout' => 60 // 超时时间(单位:s)
)
);
$context = stream_context_create($options);
$result = file_get_contents($posturl, false, $context);
echo $result;
封装成函数
function send_data($url, $post_data) {
$postdata = http_build_query($post_data);//格式化数据
$options = array(
'http' => array(
'method' => 'POST',//发送方式,post或get
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $postdata,
'timeout' => 60 // 超时时间(单位:s)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return $result;
}
使用时调用
$posturl="https://notes.zeng.love";
$post_data = array(
'key1' => 'value1',
'key2' => 'value2'
);
$res=send_data($posturl, $post_data);
当然,不得不说,file_get_contents 在使用过程中,会出现一些始料未及的错误,功能也不够强大,为了使您的程序最大限度的兼容,还是推荐使用 curl。...
本脚本是缤纷彩虹天地出品的一键安装 Kangle+Easypanel+MySQL+PHP 集合的脚本。
脚本简介
彩虹 Kangle 一键脚本,是一款可以一键安装Kangle+Easypanel+MySQL+PHP 集合的 Linux 脚本。 脚本本身集成:PHP5.3-8.3、MYSQL5.6-8.0,支持极速安装和编译安装2种模式,支持CDN专属安装模式。同时也对 Easypanel 面板进行了大量优化。
脚本特点
有国内和国外2个文件下载节点,提升安装速度
自带Kangle商业版最新版本免费使用
支持EP前台自由切换 PHP5.3-8.3 安装前可选 MySQL5.6、5.7、8.0 版本
预先设置各 PHP 版本 PHP.ini 安全问题
安装前可自定义数据库密码,避免安装完成后再设置的麻烦
支持自定义403.404.503.504等错误页面
脚本中可切换其它几套EP用户后台模板
脚本中集成 Linux 工具箱,可一键更换 Yum 源、更换 DNS 、设置 Swap 、同步时间、清理垃圾等
修改 kangle 二进制文件以提升错误页加载速度
基于原版的优化内容
EP源码全解密并升级 Smarty 框架
SSL证书可同步到 CDN 节点
SSL配置页面新增"HTTP跳转到HTTPS"选项
SSL配置页面新增"开启HTTP2"选项
CDN可以给单个域名设置SSL证书
增加独立的PHP版本切换页面
EP管理员后台增加选项:默认PHP版本、允许域名泛绑定
修复带有空格的文件名无法解压和重命名的问题
CDN绑定域名可以自定义回源协议,增加tcp四层转发
优化防CC设置页面,支持设置IP和URL白名单
清除缓存页面支持批量清除
支持设置URL黑名单
绑定域名页面新增编辑按钮
* EP升级方法:脚本主菜单选择单独安装/更新组件,然后选择更新Easypanel
支持的系统
CentOS Stream 9(RHEL 9 / Rocky 9 / Alma 9)
CentOS Stream 8(RHEL 8 / Rocky 8 / Alma 8 / OpenCloudOS 8 / AlibabaCloud 3)
CentOS 7(OpenCloudOS 7 / AlibabaCloud 2)
CentOS 6(不支持安装PHP7.4及以上版本)
安装方式
复制以下指令到ssh连接软件粘贴执行
yum -y install wget;wget http://kangle.cccyun.cn/start;sh start
开源地址:https://github.com/netcccyun/easypanel
本文转自http://kangle.cccyun.cn/...
由缤纷彩虹天地出品的 Windows 版 Kangle+PHP+Easypanel+MySQL 安装套件,绿色免安装,解压即用。Kangle采用最新3.5.21.4 企业版并集成授权文件,可直接使用。Easypanel 采用与 Linux 脚本一致的全解密优化版本。
功能特色
可选下载PHP5.3-8.2版本,MySQL5.5-8.0版本
所有PHP版本均是最新版,并进行php.ini安全优化
修改kangle二进制文件以提升错误页加载速度
集成IIS插件,可开通IIS空间,支持NET2.0/4.0切换(需自行安装IIS)
Easypanel优化内容可参考此文:Kangle 一键安装脚本
支持开CDN或做子节点,支持与Linux版Kangle同步数据。
支持的操作系统
64位 Windows 2008/2008R2/2012/2012R2/2016/2019/2022 并且未安装过其他Web软件
安装步骤
下载并安装微软常用运行库合集。
下载 kangle&php&easypanel.7z 并解压到任意磁盘根目录。不要解压到桌面!也不要解压到子目录!
管理员模式运行 安装.bat,执行完脚本之后会自动启动服务,然后访问 http://IP:3312 进入 EP 面板,默认管理员账号密码:admin/kangle
上述压缩包自带 PHP5.6 版本,如需其他 PHP 版本,从网盘下载后放到 kangle/ext/ 目录下解压。重启 Kangle 生效。
可根据需要决定是否安装MySQL(例如开CDN就不需要安装),从网盘下载 MySQL 压缩包后,解压到磁盘根目录,执行 安装.bat,安装成功后会显示root密码。如果忘记root密码,可重复执行 安装.bat 进行密码重置,不会影响已有数据(不建议使用MySQL5.5版本)。
常见问题
EP后台服务器设置,物理盘选项为空:
是因为系统缺少.NET3.5组件,从网盘下载对应系统版本的NET3.5压缩包,解压后执行 install.bat 安装。
下载地址:https://www.123pan.com/s/cmeA-ArVS3
本文转自https://blog.cccyun.cn/post-465.html...
在使用PHP进行开发时,我们经常需要从远程服务器下载文件。当文件体积较大时,普通的文件操作和 cURL 方法可能会因为内存限制或执行时间限制而失败。本文将介绍如何使用 PHP 中的 cURL 扩展来高效地下载远程的超大文件。
解决方案
为了避免内存限制,我们可以一边读取 cURL 响应,一边将数据写入文件流,而不是一次性将整个文件内容载入内存。
技术要点
cURL初始化:初始化cURL会话,并设置相关选项。
流式下载:通过CURLOPT_WRITEFUNCTION和CURLOPT_READFUNCTION选项自定义读写函数,实现流式下载。
进度处理:可以使用CURLOPT_NOPROGRESS和CURLOPT_PROGRESSFUNCTION来监控下载进度。
错误处理:正确处理cURL执行中的错误。
涉及的难点讲解
1. 流式下载
流式下载的关键在于如何一边从远程服务器接收数据,一边将数据写入本地文件系统。
2. PHP配置
对于大文件下载,可能需要调整PHP配置中的memory_limit和max_execution_time以避免脚本执行超时。
代码示例
<?php
// 初始化cURL会话
$ch = curl_init('http://example.com/large-file.zip');
// 设置cURL选项
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // 不返回响应内容
curl_setopt($ch, CURLOPT_NOPROGRESS, false); // 启用进度条
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progressCallback'); // 设置进度回调函数
// 自定义写文件函数
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) {
// 将数据写入文件
$fp = fopen('large-file.zip', 'a'); // 'a'模式以追加方式打开文件
fwrite($fp, $data);
fclose($fp);
return strlen($data); // 返回写入的字节数
});
// 执行cURL会话
curl_exec($ch);
// 关闭cURL会话
curl_close($ch);
// 进度回调函数
function progressCallback($ch, $download_size, $downloaded, $upload_size, $uploaded) {
static $previous = 0;
if (time() - $previous > 1) { // 每秒更新一次进度
$previous = time();
$percent = (int) ($downloaded / $download_size * 100);
echo "Downloaded $percent%...\n";
}
}
?>
注意事项
确保PHP配置允许足够的执行时间和内存使用。
在生产环境中,应避免将错误信息输出到浏览器,以免泄露敏感信息。
对于安全性要求较高的应用,应验证SSL证书。
通过上述方法,我们可以有效地使用PHP和cURL下载远程的超大文件,同时保持内存使用在合理范围内,并能够监控下载进度。
稍简单的实现
function downloadFile($url, $path)
{
$fp = fopen($path, 'w');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
}
本文转自:https://www.lvtao.net/dev/how-to-download-large-remote-files-using-curl-in-php.html...
今天闲逛时发现一篇技术文章,非常不错,就转过来了。
以下是全文:
先声明一下,这是我自己内网使用的一个简单的管理工具,所以安全性方面我肯定是没有测试的~ 如果你要放在公网,请添加相关的权限认证及sql防注入等处理
在开发过程中,我们经常需要一个简单易用的数据库管理工具来快速查看和操作数据库。本文将介绍如何使用PHP为SQLite开发一款强大的数据库管理工具,并将其部署在PHP环境中,以便于快速访问和使用。
SQLite是一个轻量级的嵌入式数据库,非常适合用于小型项目或原型开发。然而,SQLite自带的命令行工具虽然功能强大,但对于非技术人员来说,使用起来并不直观。因此,我们决定使用PHP来构建一个简单的Web界面,以便于用户通过浏览器来管理和操作SQLite数据库。
先预览一下(嘿嘿~丑是丑了点~但已经完全够用了~~):
功能概述
我们的SQLite数据库管理工具具备以下功能:
表管理:
列出数据库中的所有表。
创建新表。
删除现有表。
字段管理:
查看表结构。
添加新字段。
删除现有字段。
编辑字段属性(字段名、类型、默认值等)。
记录管理:
删除表中的记录。
SQL执行器:
执行自定义SQL查询。
显示查询结果。
代码实现
以下是我们的PHP代码实现,展示了如何使用PDO连接SQLite数据库,并实现上述功能,文件名为db.php,就一个文件~
<?php
try {
$db = new PDO('sqlite:my.db');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if (!$db) {
die('数据库连接失败,请检查配置。');
}
// 获取表列表
function listTables(PDO $db) {
$stmt = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'");
return $stmt->fetchAll(PDO::FETCH_COLUMN);
}
// 获取表结构
function getTableStructure(PDO $db, $tableName) {
$stmt = $db->query("PRAGMA table_info($tableName)");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 动态处理表单操作
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
$table = $_POST['table'] ?? '';
if ($action === 'create-table') {
$tableName = $_POST['table_name'];
$db->exec("CREATE TABLE $tableName (id INTEGER PRIMARY KEY AUTOINCREMENT)");
header("Location: db.php?table=$tableName");
exit();
}
if ($action === 'delete-table') {
$db->exec("DROP TABLE $table");
header("Location: db.php");
exit();
}
if ($action === 'add-field') {
$fieldName = $_POST['field_name'];
$fieldType = $_POST['field_type'];
$defaultValue = $_POST['default_value'] ?? null;
// 构造字段定义
$fieldDefinition = "$fieldName $fieldType";
if ($defaultValue !== null && $defaultValue !== '') {
// 如果默认值是字符串,需要添加引号
$defaultValue = is_numeric($defaultValue) ? $defaultValue : "'$defaultValue'";
$fieldDefinition .= " DEFAULT $defaultValue";
}
// 添加字段
$db->exec("ALTER TABLE $table ADD COLUMN $fieldDefinition");
header("Location: db.php?table=$table");
exit();
}
if ($action === 'delete-field') {
$fieldName = $_POST['field_name'];
// 获取原表结构
$structure = getTableStructure($db, $table);
// 构造新表的字段定义,排除要删除的字段
$columns = [];
$columnsForInsert = [];
foreach ($structure as $column) {
if ($column['name'] !== $fieldName) {
$columnDefinition = $column['name'] . ' ' . $column['type'];
if ($column['notnull']) {
$columnDefinition .= ' NOT NULL';
}
if ($column['dflt_value'] !== null) {
// 检查并处理默认值
if (is_numeric($column['dflt_value'])) {
$defaultValue = $column['dflt_value']; // 数字直接使用
} else {
// 如果不是数字且未包裹引号,则包裹一次单引号
$defaultValue = trim($column['dflt_value'], "'"); // 去掉可能存在的多余引号
$defaultValue = "'" . str_replace("'", "''", $defaultValue) . "'";
}
$columnDefinition .= " DEFAULT $defaultValue";
}
if ($column['pk']) {
$columnDefinition .= ' PRIMARY KEY';
}
$columns[] = $columnDefinition;
$columnsForInsert[] = $column['name'];
}
}
$newColumnsStr = implode(', ', $columns);
$columnsForInsertStr = implode(', ', $columnsForInsert);
// 创建新表并迁移数据
$db->exec("CREATE TABLE ${table}_new ($newColumnsStr)");
$db->exec("INSERT INTO ${table}_new ($columnsForInsertStr) SELECT $columnsForInsertStr FROM $table");
// 删除旧表并重命名新表
$db->exec("DROP TABLE $table");
$db->exec("ALTER TABLE ${table}_new RENAME TO $table");
header("Location: db.php?table=$table");
exit();
}
if ($action === 'edit-field') {
$oldFieldName = $_POST['old_field_name'];
$newFieldName = $_POST['new_field_name'];
$newFieldType = $_POST['new_field_type'];
$defaultValue = $_POST['default_value'] ?? null;
// 获取表结构,创建新的表结构
$structure = getTableStructure($db, $table);
$columns = [];
$columnsForInsert = [];
foreach ($structure as $column) {
if ($column['name'] === $oldFieldName) {
// 针对被编辑的字段,使用表单中提交的值
$fieldDefinition = "$newFieldName $newFieldType";
// 设置新默认值,仅对被修改字段生效
if ($defaultValue !== null && $defaultValue !== '') {
// 检查默认值是否已被包裹引号
if (!is_numeric($defaultValue) && !preg_match("/^'.*'$/", $defaultValue)) {
// 为字符串添加引号并转义内部引号
$defaultValue = "'" . str_replace("'", "''", $defaultValue) . "'";
}
$fieldDefinition .= " DEFAULT $defaultValue";
}
// 保留字段的非空和主键约束
if ($column['notnull']) {
$fieldDefinition .= " NOT NULL";
}
if ($column['pk']) {
$fieldDefinition .= " PRIMARY KEY";
}
$columns[] = $fieldDefinition;
$columnsForInsert[] = $newFieldName;
} else {
// 对于未修改的字段,完全保留其原始定义
$fieldDefinition = $column['name'] . ' ' . $column['type'];
if ($column['dflt_value'] !== null) {
// 仅保留字段的原始默认值,不改变
$originalDefaultValue = is_numeric($column['dflt_value'])
? $column['dflt_value']
: "'" . str_replace("'", "''", trim($column['dflt_value'], "'")) . "'";
$fieldDefinition .= " DEFAULT $originalDefaultValue";
}
// 保留非空和主键约束
if ($column['notnull']) {
$fieldDefinition .= " NOT NULL";
}
if ($column['pk']) {
$fieldDefinition .= " PRIMARY KEY";
}
$columns[] = $fieldDefinition;
$columnsForInsert[] = $column['name'];
}
}
$newColumnsStr = implode(', ', $columns);
$columnsForInsertStr = implode(', ', $columnsForInsert);
// 创建新表并迁移数据
$db->exec("CREATE TABLE ${table}_new ($newColumnsStr)");
$db->exec("INSERT INTO ${table}_new ($columnsForInsertStr) SELECT $columnsForInsertStr FROM $table");
// 删除旧表并重命名新表
$db->exec("DROP TABLE $table");
$db->exec("ALTER TABLE ${table}_new RENAME TO $table");
header("Location: db.php?table=$table");
exit();
}
if ($action === 'delete-record') {
$id = $_POST['id'];
$db->exec("DELETE FROM $table WHERE id = $id");
header("Location: db.php?table=$table");
exit();
}
if (isset($_POST['sql_query'])) {
$sqlQuery = trim($_POST['sql_query']);
try {
$stmt = $db->query($sqlQuery);
if ($stmt) {
$queryResults = $stmt->fetchAll(PDO::FETCH_ASSOC);
} else {
$queryResults = [];
}
} catch (Exception $e) {
$queryError = $e->getMessage();
}
}
}
$tables = listTables($db);
$currentTable = $_GET['table'] ?? null;
$tableStructure = $currentTable ? getTableStructure($db, $currentTable) : [];
} catch (Exception $e) {
die('数据库操作失败: ' . $e->getMessage());
}
?>
篇幅有限,只展示了纯 php 部分代码,可点击文末的链接下载文件查看全部代码。
本文转自:https://www.lvtao.net/dev/php-sqlite-manage-tool.html
下载:db.zip...