Gitlab: PHP项目CI/CD实践
目录
1 说明
2 CI/CD
2.1 部署方式一:增量部署
2.1.1 目标服务器准备
2.2.2 Gitlab及Envoy脚本
2.2 部署方式二:镜像构建与部署
2.2.1 推送到私有化容器仓库
准备工作
脚本
要点
2.2.2 推送到hub.docker.com
准备工作
脚本
3 参考:
1 说明
- 以一个laravel blog项目为例,做dev分支的CI/CD实践
- 结合laravel envoy工具做多个远程服务器部署,分两种方式:A. 增量部署 B.镜像构建与部署
服务器:
| Site | Server | IP | 站点目录 |
|---|---|---|---|
| team1-prj2.dev.ia | host001.dev.ia | 192.168.0.130 | /www/wwwroot/team1-prj2.dev.ia |
| team1-prj2.dev.ia | host002.dev.ia | 192.168.0.131 | /www/wwwroot/team1-prj2.dev.ia |
2 CI/CD
2.1 部署方式一:增量部署
通过Lavavel/Envoy和git拉取新版本文件进行部署
2.1.1 目标服务器准备
- php8.2, 安装所需扩展,务必在cli下测试是否正常, 有些被disable的functions要打开
- composer self-update, 兼容php8.2
- 使用Laravel/Envoy分发部署,确保Envoy.blade.php是utf8格式文件
- 站点目录结构
root@host001:/www/wwwroot/team1-prj2.dev.ia# tree -d -L 3 ./ ./ ├── current -> /www/wwwroot/team1-prj2.dev.ia/releases/default ├── releases │ └── default │ ├── app │ ├── bootstrap │ ├── config │ ├── database │ ├── public │ ├── resources │ ├── routes │ ├── storage -> /www/wwwroot/team1-prj2.dev.ia/storage │ ├── tests │ └── vendor └── storage├── app│ └── public├── framework│ ├── cache│ ├── sessions│ ├── testing│ └── views└── logs
说明:
| team1-prj2.dev.ia | 应用目录 |
| team1-prj2.dev.ia/releases | 版本发布目录,这里只设置了一个default目录,也可根据需要做日期变量发布 |
| team1-prj2.dev.ia/current | 链接到最新版本,被nginx访问的站点目录路径 current -> /www/wwwroot/team1-prj2.dev.ia/releases/default/ |
| team1-prj2.dev.ia/storage | 链接到最新版本的应用数据保存目录,如:日志,缓存等 storage -> /www/wwwroot/team1-prj2.dev.ia/storage |
| team1-prj2.dev.ia/.dev | .dev文件是运维人员建立的服务器定制环境文件,不进入仓库,链接到项目同名文件 .env -> /www/wwwroot/team1-prj2.dev.ia/.env* |
| team1-prj2.dev.ia/releases/default/.gitlab-ci.yml | gitlab 部署脚本 |
| team1-prj2.dev.ia/releases/default/Envoy.blade.php | envoy 部署脚本 |
nginx配置
server
{listen 80;server_name team1-prj2.dev.ia;index index.php index.html index.htm default.php default.htm default.html;root /www/wwwroot/team1-prj2.dev.ia/current/public;#CERT-APPLY-CHECK--START# 用于SSL证书申请时的文件验证相关配置 -- 请勿删除include /www/server/panel/vhost/nginx/well-known/team1-prj2.dev.ia.conf;#CERT-APPLY-CHECK--END#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则#error_page 404/404.html;#SSL-END#ERROR-PAGE-START 错误页配置,可以注释、删除或修改#error_page 404 /404.html;#error_page 502 /502.html;#ERROR-PAGE-END#PHP-INFO-START PHP引用配置,可以注释或修改include enable-php-82.conf;#PHP-INFO-END#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效include /www/server/panel/vhost/rewrite/team1-prj2.dev.ia.conf;#REWRITE-END#禁止访问的文件或目录location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md){return 404;}#一键申请SSL证书验证目录相关设置location ~ \.well-known{allow all;}#禁止在证书验证目录放入敏感文件if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {return 403;}location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${expires 30d;error_log /dev/null;access_log /dev/null;}location ~ .*\.(js|css)?${expires 12h;error_log /dev/null;access_log /dev/null;}location / {try_files $uri $uri/ /index.php?$query_string;}access_log /www/wwwlogs/team1-prj2.dev.ia.log;error_log /www/wwwlogs/team1-prj2.dev.ia.error.log;
}
2.2.2 Gitlab及Envoy脚本
.gitlab-ci.yml
# default:
# image: edbizarro/gitlab-ci-pipeline-php:7.4
#default:
# image: bennybi/php8.2
# image: bennybi/php7.4stages:- test- deploy.init_ssh: &init_ssh |which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )eval $(ssh-agent -s)echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/nullmkdir -p ~/.sshchmod 700 ~/.ssh[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/configcache:key: ${CI_COMMIT_REF_SLUG}paths:- vendor/unit_test:stage: testtags:- phpscript:- cp .env.test .env- composer install- composer global require "laravel/envoy"- php artisan key:generate- php artisan migrate- vendor/bin/phpunitdeploy_dev:stage: deploytags:- phpenvironment:name: devurl: http://team1-prj2.dev.iascript:- *init_ssh- vendor/bin/envoy run deploy --branch="$CI_COMMIT_BRANCH" --commit="$CI_COMMIT_SHA"rules:- if: $CI_COMMIT_BRANCH == "dev"deploy_live:stage: deploytags:- phpscript:- *init_ssh- vendor/bin/envoy run deploy --commit="$CI_COMMIT_SHA"environment:name: liveurl: http://team1-prj2.dev.iawhen: manualrules:- if: $CI_COMMIT_BRANCH == "live"
Envoy.blade.php
@servers(['local' => 'deployer@host001.dev.ia','staging' => 'deployer@host002.dev.ia'])@setup$repository = 'git@host001.dev.ia:dev1/team1-prj2.git';$releases_dir = '/www/wwwroot/team1-prj2.dev.ia/releases';$app_dir = '/www/wwwroot/team1-prj2.dev.ia';$release = 'default';$new_release_dir = $releases_dir .'/'. $release;$user = get_current_user();
@endsetup@story('deploy', ['on' => ['local','staging']])sync_repositoryrun_composerupdate_symlinks
@endstory@task('sync_repository')echo "Current User: {{$user}}, branch:{{$branch}}, commit:{{$commit}}"if [ -d "{{$new_release_dir}}" ]; thenecho 'Pulling repository'cd {{ $new_release_dir }}git checkout {{ $branch }}git fetchgit reset --hard HEADgit merge origin/{{ $branch }}elseecho 'Cloning repository'[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}git clone --branch {{ $branch }} --single-branch --depth 1 {{ $repository }} {{ $new_release_dir }}cd {{ $new_release_dir }}git reset --hard {{ $commit }}git config --global --add safe.directory '*'fi
@endtask@task('run_composer')echo "Starting deployment ({{ $release }})"cd {{ $new_release_dir }}composer install --prefer-dist --no-scripts -q -o
@endtask@task('update_symlinks')if [ ! -d "{{ $app_dir }}/current" ]; thenecho "Linking storage directory"{{-- rm -rf {{ $new_release_dir }}/storage --}}mv {{ $new_release_dir }}/storage {{ $app_dir }}ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storageecho 'Linking .env file'ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.envecho 'Linking current release'ln -nfs {{ $new_release_dir }} {{ $app_dir }}/currentchmod 775 -Rf {{ $releases_dir }}fichmod 775 -Rf {{ $new_release_dir }}/storage{{-- chown deployer:www -Rf {{ $new_release_dir }}/.git --}}
@endtask
2.2 部署方式二:镜像构建与部署
2.2.1 推送到私有化容器仓库
准备工作
- 新建项目team1-prj1,初始化git 仓库为:http://host001.dev.ia:18181/dev1/team1-prj1.git
- 建好容器仓库(见前文相关部分)
- 需要在Admin Area->CI/CD->Variables添加docker访问用户变量
$LOCAL_REGISTRY_LOGIN = your docker username
$LOCAL_REGISTRY_PASSWORD
脚本
项目中添加Dockerfile 文件,这里用到的原型镜像是我之前定制的php8.2
# Set the base image for subsequent instructions
FROM bennybi/php8.2:latest# Update packages
RUN apt-get update# Install PHP and composer dependencies
# RUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev# Clear out the local repository of retrieved package files
RUN apt-get clean# Install needed extensions
# Here you can install any other extension that you need during the test and deployment process
# RUN docker-php-ext-install mcrypt pdo_mysql zip# Install Composer
RUN curl --silent --show-error "https://getcomposer.org/installer" | php -- --install-dir=/usr/local/bin --filename=composer# Install Laravel Envoy
RUN composer global require "laravel/envoy=~1.0"# Laravel? Add your user
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www# Copy existing application directory contents
COPY . /var/www# Copy existing application directory permissions
COPY --chown=www:www . /var/www# Change current user to www
USER www# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
.gitlab-ci.yml
default:image: docker:19.03.8services:- mysql:5.7before_script:- docker infovariables:MYSQL_DATABASE: testMYSQL_ROOT_PASSWORD: fa843c707ce26702DB_HOST: host001.dev.iaDB_USERNAME: developerstages:- test- build# - deployunit_test:stage: testtags:- phpscript:- cp .env.test .env- composer install- php artisan key:generate- php artisan migrate- vendor/bin/phpunitbuild_image:stage: buildvariables:REGISTRY_URL: 'http://host001.dev.ia:5050'DOCKER_IMAGE_TAG: 'host001.dev.ia:5050/dev1/team1-prj1'tags:- phpscript:- docker login ${REGISTRY_URL} -u $LOCAL_REGISTRY_LOGIN -p $LOCAL_REGISTRY_PASSWORD- docker build --output type=registry,oci-mediatypes=false --cache-from "${DOCKER_IMAGE_TAG}" -t "${DOCKER_IMAGE_TAG}" --push --provenance=false .# - docker push ${DOCKER_IMAGE_TAG}:latest- docker push ${DOCKER_IMAGE_TAG}rules:- if: $CI_COMMIT_BRANCH == "dev"# deploy_dev:
# stage: deploy
# tags:
# - php
# script:
# - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# - eval $(ssh-agent -s)
# - ssh-add <(echo "$SSH_PRIVATE_KEY")
# - mkdir -p ~/.ssh
# - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
# # - ~/.composer/vendor/bin/envoy run deploy --commit="$CI_COMMIT_SHA"
# environment:
# name: dev
# url: http://team1-prj1.dev.ia
# when: manual
# rules:
# - if: $CI_COMMIT_BRANCH == "dev"
要点
- 注意build时所需的参数,缺少会诱发错误: “Invalid tag: missing manifest digest”
We used the buildx flag “–output type=registry,oci-mediatypes=false” to generate a Docker v2.2 manifest list. We could set the value to “true” and generate an OCI manifest index, but the GitLab UI will incorrectly display “Invalid tag: missing manifest digest”.
推送结果图示:


2.2.2 推送到hub.docker.com
准备工作
- 新建项目team1-prj1,初始化git 仓库为:http://host001.dev.ia:18181/dev1/team1-prj1.git
- 构建的镜像将push到hub.docker.com,因此需要在Admin Area->CI/CD->Variables添加docker访问用户变量
$DOCKER_LOGIN = your docker username
$DOCKER_PASSWORD
脚本
Dockerfile
同上 ...
.gitlab-ci.yml
default:image: docker:19.03.8services:- mysql:5.7before_script:- docker infovariables:MYSQL_DATABASE: testMYSQL_ROOT_PASSWORD: fa843c707ce26702DB_HOST: host001.dev.iaDB_USERNAME: developerstages:- test- build# - deployunit_test:stage: testtags:- phpscript:- cp .env.test .env- composer install- php artisan key:generate- php artisan migrate- vendor/bin/phpunitbuild_image:stage: buildvariables:DOCKER_IMAGE_TAG: 'bennybi/team1-prj1'tags:- phpscript:- docker build --cache-from "${DOCKER_IMAGE_TAG}" -t "${DOCKER_IMAGE_TAG}" .- docker login --username $DOCKER_LOGIN --password $DOCKER_PASSWORD# - docker run my-docker-image /script/to/run/tests- docker push ${DOCKER_IMAGE_TAG}:latestrules:- if: $CI_COMMIT_BRANCH == "dev"# deploy_dev:
# stage: deploy
# tags:
# - php
# script:
# - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# - eval $(ssh-agent -s)
# - ssh-add <(echo "$SSH_PRIVATE_KEY")
# - mkdir -p ~/.ssh
# - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
# # - ~/.composer/vendor/bin/envoy run deploy --commit="$CI_COMMIT_SHA"
# environment:
# name: dev
# url: http://team1-prj1.dev.ia
# when: manual
# rules:
# - if: $CI_COMMIT_BRANCH == "dev"
3 参考:
- GitLab: automated build and publish of multi-platform container image with GitLab pipeline | Fabian Lee : Software Engineer
- https://jaumemule.medium.com/build-a-php8-0-fpm-gitlab-ci-cd-application-docker-google-cloud-5f2868e8370
- https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
- https://github.com/papertank/envoy-deploy/blob/master/readme.md
- https://warrickbayman.medium.com/zero-downtime-laravel-deployments-with-envoy-version-2-227c8259e31c
- Test and deploy Laravel applications with GitLab CI/CD and Envoy | GitLab
- GitLab CI/CD examples | GitLab
- 使用GitLab Runner为基于Laravel的PHP项目进行部署
- GitLab CI/CD for Beginners [FREE Course] - DEV Community
相关文章:
Gitlab: PHP项目CI/CD实践
目录 1 说明 2 CI/CD 2.1 部署方式一:增量部署 2.1.1 目标服务器准备 2.2.2 Gitlab及Envoy脚本 2.2 部署方式二:镜像构建与部署 2.2.1 推送到私有化容器仓库 准备工作 脚本 要点 2.2.2 推送到hub.docker.com 准备工作 脚本 3 参考&#x…...
c语言游戏实战(10):坤坤的篮球回避秀
前言: 这款简易版的球球大作战是博主耗时两天半完成的,玩家需要控制坤坤在游戏界面上移动,来躲避游戏界面上方不断掉下来的篮球。本游戏使用C语言和easyx图形库编写,旨在帮助初学者了解游戏开发的基本概念和技巧。 在开始编写代…...
初学arp欺骗
首先准备一台靶机这里用虚拟机的win10 已知网关与ip地址(怕误伤) 现在返回kali从头开始 首先探测自己的网关 然后扫内网存活的ip 发现有3台 用nmap扫一下是哪几台 成功发现我们虚拟机的ip 现在虚拟机可以正常访问网络 接下来直接开梭 ip网关 返回虚拟机…...
ftp几个常见错误问题及解决办法
1、无法上传网页,FTP故障-提示“无法连接服务器”错误。 问题出现原因:FTP客户端程序设置问题,客户上网线路问题,ftp服务器端问题。 处理方法:建议客户使用CUTPFTP软件来上传客户的网页,在“F…...
鸿蒙App开发新思路:小程序转App
国家与国家之间错综复杂,在谷歌的安卓操作系统“断供”后,鸿蒙系统的市场化&独立化的道路便显而易见了。 2024年1月18日,华为宣布,不再兼容安卓的“纯血鸿蒙”--HarmonyOS NEXT鸿蒙星河版最终面世,并与2024年Q4正…...
C++17之std::invoke: 使用和原理探究(全)
C进阶专栏:http://t.csdnimg.cn/5mV9r 目录 1.概述 2.辅助类 3.原理分析 4.总结 1.概述 在之前的 C 版本中,要调用不同类型的可调用对象,需要使用不同的语法,例如使用函数调用运算符 () 来调用函数或函数指针,使用…...
shadertoy 游戏《来自星尘》摇杆复刻
正确的做法应该是上 noise 而不是叠加 sin 波,不过如果不想麻烦的话叠波还是一个不错的选择:整体效果如下,已经非常形似 直接上链接:Shader - Shadertoy BETA float radiusScale 0.9; float variation(vec2 v1, vec2 v2, float …...
获取PDF中的布局信息——如何获取段落
PDF解析是极其复杂的问题。不可能靠一个工具解决全部问题,尤其是五花八门,格式不统一的PDF文件。除非有钞能力。如果没有那就看看可以分为哪些问题。 提取文本内容,提取表格内容,提取图片。我认为这些应该是分开做的事情。python有…...
Laya2.13.3在Web条件下使用键盘控制相机移动
需求:在Laya开发时,常常没法移动相机来观察场内的环境,故制作一个移动相机的脚本来是实现此功能,目前先使用键盘后续会添加鼠标控制移动旋转等功能。 onEnable(){this.camera new Laya.Camera(0, 0.1, 100);this._tempVector3 n…...
centos系统服务器在Jenkins执行playwright UI自动化测试框架
centos系统服务器在Jenkins执行playwright UI自动化测试框架 1. centos7.9系统中安装playwright环境报错 playwright/driver/node: /lib64/libc.so.6: version `GLIBC_2.25 not found经过查找资料,playwright 仅支持Ubuntu系统,其他的Linux服务器系统不支持,为此采用docke…...
boost.redis崩溃的解决方法
使用boost.redis的协程一定要co_spawn在strand对象中。 正确的用法: boost::asio::co_spawn(boost::dasio::make_strand(ioc),XXXCoroutine(),boost::asio::detached ); 错误的用法: boost::asio::co_spawn(ioc,XXXCoroutine(),boost::asio::detache…...
蓝桥杯——123
123 二分等差数列求和前缀和数组 题目分析 连续一段的和我们想到了前缀和,但是这里的l和r的范围为1e12,明显不能用O(n)的时间复杂度去求前缀和。那么我们开始观察序列的特点,可以按照等差数列对序列进行分块。如上图,在求前10个…...
嵌入式基础知识-信号量,PV原语与前趋图
本篇来介绍信号量与PV原语的一些知识,并介绍其在前趋图上的应用分析。本篇的知识属于操作系统部分的通用知识,在嵌入式软件开发中,同样会用到这些知识。 1 信号量 信号量是最早出现的用来解决进程同步与互斥问题的机制(可以把信…...
代码遗产:探索祖传代码的历史、挑战与现代融合艺术
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua,在这里我会分享我的知识和经验。&#x…...
Vue3:用vite创建Vue3项目
一、简介 vite是新一代前端构建工具,官网地址:https://vitejs.cn vite的优势如下: 轻量快速的热重载(HMR),能实现极速的服务启动。对 TypeScript、JSX、CSS 等支持开箱即用。真正的按需编译,不…...
STM32 (2)
1.stm32编程模型 将C语言程序烧录到芯片中会存储在单片机的flsah存储器中,给芯片上电后,Flash中的程序会逐条进入到CPU中去执行,进而CPU去控制各种模块(即外设)去实现各种功能。 2.寄存器和寄存器编程 CPU通过控制其…...
docker部署nginx+反向代理配置/代理宿主机网段服务器
1、安装docker,并运行 2、拉取nginx镜像 docker pull nginx3、运行nginx容器,将文件拷贝至本地,并将nginx容器删除 #运行nginx容器 docker run -id --name mynginx -p 8080:80 nginx#将配置文件从容器内拷贝至本地 docker cp 容器ID:/et…...
初识Hive
官网地址为: Design - Apache Hive - Apache Software Foundation 一、架构 先来看下官网给的图: 图上显示了Hive的主要组件及其与Hadoop的交互。Hive的主要组件有: UI: 用户向系统提交查询和其他操作的用户界面。截至2011年&…...
Google发布Genie硬杠Sora:通过大量无监督视频训练最终生成可交互虚拟世界
前言 Sora 问世才不到两个星期,谷歌的世界模型也来了,能力看似更强大:它生成的虚拟世界自主可控 第一部分 首个基础世界模型Genie 1.1 Genie是什么 Genie是第一个以无监督方式从未标记的互联网视频中训练的生成式交互环境(the first gener…...
全球首台!未磁科技256通道无液氦脑磁图仪及芯片化原子磁力计正式发布
2024年2月3日,由北京未磁科技有限公司牵头的国家重点研发计划诊疗装备与生物医用材料重点专项“新型无液氦脑磁图系统研发”项目2023年度总结会暨2024年推进会顺利召开。会上发布了项目取得的重大成果——全球首台256通道无液氦脑磁图仪Marvel MEG Pro。此项重磅成果…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
