首页
Search
1
解决 docker run 报错 oci runtime error
49,335 阅读
2
WebStorm2025最新激活码
27,568 阅读
3
互点群、互助群、微信互助群
22,731 阅读
4
常用正则表达式
21,540 阅读
5
罗技鼠标logic g102驱动程序lghub_installer百度云下载windows LIGHTSYNC
19,318 阅读
自习室
CODER
课程
SEO
学习视频
手册资料
呆萌
工具软件
运维
DBA
互通有无
资源
微信群
激活工具
搞钱日记
养生记
包罗万象
登录
Search
标签搜索
DeepSeek
学习指北
Prompt
提示词
Loong
累计撰写
179
篇文章
累计收到
0
条评论
首页
栏目
自习室
CODER
课程
SEO
学习视频
手册资料
呆萌
工具软件
运维
DBA
互通有无
资源
微信群
激活工具
搞钱日记
养生记
包罗万象
页面
搜索到
143
篇与
的结果
2019-02-16
商品sku匹配及属性可选状态
最近在做商品sku的时候遇到了一些困惑,记录一下,以备日后会看。 先说一说需求: 1.根据选中的SKU,显示对应的SKU图片,没有选中的SKU时,默认展示SPU商品图,单击放大预览; 2.每个属性下属性值有多个时,默认不选,只有一个时,默认选中; 3.后台没有设置SKU时,则无属性值展示; 4.选中交互:选中某一个属性下属性值时,检查其他属性的属性值,哪些不能组合为一个SKU,不能组合的属性值只读,原选中的则取消选中。 已上就是给出的文字需求,在需求讨论的时候产品定了调调,通过既定的属性去确定一个sku,即所有未选择的属性假定一个初始值。一听心里乐了,所有选中的属性都已知,排序之后再匹配不就是轻松确定sku了嘛,美滋滋。/** * 获取商品sku属性(初始默认选中,已经被否了呀) */ public function goods_sku_version_1 (){ $goodsId = $this->post['goods_id'] or $this->response(201, 'goods_id不能为空'); $catId = mall_database_execute('goods') ->where(['goods_id' => $goodsId, 'is_on_sale'=> 1, 'is_delete' => 0]) ->getField('goods_type') or $this->response(208, '商品不存在'); //构建查询条件 $where = ['gs.goods_id'=> $goodsId]; $attrArr = []; if (!empty($this->post['attr_id'])){ $attrArr = explode(',', $this->post['attr_id']); sort($attrArr); //升序 $where['gs.attr_id_arr'] = implode(',', $attrArr); } //获取sku信息 $this->rows['info'] = mall_database_execute('goods_sku')->alias('AS gs') ->where($where) ->find() or $this->response(208, 'sku不存在'); if (empty($this->post['attr_id'])) $attrArr = explode(',', $this->rows['info']['attr_id_arr']); //获取顶级sku列表 $this->rows['attribute'] = mall_database_execute('goods_sku_list')->alias('AS gsl') ->field('ga.attr_id, ga.attr_type, ga.attr_name, gsl.attr_values_arr') ->join(mall_database_table('goods_attribute').' AS ga ON ga.attr_id = gsl.attr_id', 'LEFT') ->where([ 'gsl.goods_id' => $goodsId, 'gsl.status' => 1 ]) ->select() ? : ''; if (!empty($this->rows['attribute'])){ //通过二定一待,确定sku foreach ($this->rows['attribute'] as $k=>&$v){ $newAttrArr = $attrArr; $newAttrArr[$k] = '%'; $str = implode(',', $newAttrArr); $v['option'] = mall_database_execute('goods_sku') ->field('goods_sku_id,attr_id_arr,status' ) ->where([ 'goods_id' => $goodsId, 'attr_id_arr' => ['LIKE', $str] ]) ->select(); if (!empty($v['option'])){ foreach ($v['option'] as &$vo){ $newAttrArr = explode(',', $vo['attr_id_arr']); $attrInfo = mall_database_execute('goods_attribute') ->field('attr_id, attr_type, attr_name') ->where([ 'attr_id' => $newAttrArr[$k] ]) ->find(); unset($vo['attr_id_arr']); $vo = array_merge($attrInfo, $vo); } } } } $this->response(); } 本以为这样就完事了,结果没过多久需求就改了,不假定每个属性的初始值,根据用户当前选择动态匹配sku,GG。这个方案一开始没想明白的点在于,基于用户当前选择,推算所有属性的节点是否还有可选的可能(可用sku),之前想到过这一层面,想着偷懒完成需求即可,便没有深究。/** * 基于用户当前属性选择状态,获取sku,及推算每个属性的可选状态 */ public function goods_sku(){ $goodsId = $this->post['goods_id']; //检测商品是否存在 mall_database_execute('goods') ->where(['goods_id' => $goodsId, 'is_on_sale'=> 1, 'is_delete' => 0]) ->getField('goods_id') or $this->response(208, '商品不存在'); $where = [ 'goods_id' => $goodsId, 'status' => 1 ]; //获取所有可选sku的属性组合 $allSkuLists = array_column(mall_database_execute('goods_sku') ->field('attr_id_arr') ->where($where) ->select(), 'attr_id_arr'); $this->rows['sku_num'] = count($allSkuLists); if (!empty($this->post['attr_id'])){ $attrArr = explode(',', $this->post['attr_id']); foreach ($attrArr as &$vv){ if ($vv == '') $vv = '%'; } $where['old_id_arr'] = ['LIKE', implode(',', $attrArr)]; } //查询一个当前用户选择状态下满足条件的组合(先这样,等产品出了可能组合排序规则再完善) $this->rows['info'] = mall_database_execute('goods_sku') ->field('goods_sku_id,price,goods_number,attr_value,goods_thumb') ->where($where) ->find() ? : ''; if ($this->rows['info']['goods_thumb']) $this->rows['info']['goods_thumb'] = change_file_path($this->rows['info']['goods_thumb']); //获取规格 $attribute = mall_database_execute('goods_sku_list')->alias('AS gsl') ->field('ga.attr_id, ga.attr_type, ga.attr_name, gsl.attr_values_arr') ->join(mall_database_table('goods_attribute').' AS ga ON ga.attr_id = gsl.attr_id', 'LEFT') ->where([ 'gsl.goods_id' => $goodsId, 'gsl.status' => 1 ]) ->order('attr_type asc, attr_id asc') ->select(); if (!empty($attribute)){ //遍历获取所有规格的属性,并假定每种属性都不可选 foreach ($attribute as $k=>&$v){ $v['option'] = mall_database_execute('goods_attribute') ->field('attr_id,attr_type,attr_name,2 as status') ->where([ 'attr_id' => ['IN', $v['attr_values_arr']], 'status' => 1 ]) ->order('attr_id asc') ->select(); unset($v['attr_values_arr']); if (!empty($allSkuLists)){ //遍历所有属性判断基于用户选择状态下属性是否有可选方案 foreach ($v['option'] as &$vo){ //获取用户当前选择 $checkSku = explode(',', $this->post['attr_id']); //把当前属性与用户选择进行组合 $checkSku[$k] = $vo['attr_id']; //遍历所有可能的组合列表,查找是否有匹配当前的组合 foreach ($allSkuLists as $vov){ //判断条件:如果我有的你都有那就对了 $intersect = array_intersect($checkSku, explode(',', $vov)); asort($intersect); asort($checkSku); //序列化后做比较 if (implode(',', $intersect) == implode(',', array_filter($checkSku))) $vo['status'] = '1'; } } } } } $this->rows['attribute'] = $attribute ? : ''; $this->response(); }附上表结构:CREATE TABLE `fd_goods_sku` ( `goods_sku_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id', `goods_id` int(11) NOT NULL, `old_id_arr` varchar(255) NOT NULL DEFAULT '' COMMENT '没排序之前的id组合', `attr_id_arr` varchar(255) NOT NULL DEFAULT '0' COMMENT '属性id', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1正常,2失效', `price` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '售价,单位分', `goods_number` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '库存', `attr_value` varchar(255) NOT NULL DEFAULT '' COMMENT '商品自定义属性', `goods_thumb` varchar(255) NOT NULL DEFAULT '', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`goods_sku_id`), KEY `goods_id` (`goods_id`,`goods_sku_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=2208 DEFAULT CHARSET=utf8mb4 COMMENT='商品sku表'; CREATE TABLE `fd_goods_sku_list` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `goods_id` int(10) unsigned NOT NULL, `attr_id` varchar(255) NOT NULL DEFAULT '' COMMENT '属性id', `attr_values_arr` varchar(255) NOT NULL DEFAULT '' COMMENT '属性值id', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1正常,2失效', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=599 DEFAULT CHARSET=utf8mb4 COMMENT='商品已选属性表'; 以上仅作记录,如大神们有更好方案请不吝赐教。
2019年02月16日
12,938 阅读
0 评论
35 点赞
2019-01-11
docker 部署PHP+ nginx环境
首先push 两个镜像docker pull php:7.2.3-fpm docker pull nginx然后启动一个php docker run --name phpfpm -d -v /root/app:/app php:7.2.3-fpm说明一下 –name 是容器的名字 phpfpm-v 是/root/app 是本机的地址/app 是容器内部的存储位置然后再启动一个nginx docker run --name nginx_server -d -p 80:80 --link phpfpm:phpfpm -v /root/conf/nginx.conf:/etc/nginx/nginx.conf --volumes-from phpfpm nginx— link phpfrpm:phpfpm 是容器之间建立关系–volumes-from phpfpm 就是把/root/app:/app 也会导入到 容器中/app 目录 -v /root/conf/nginx.conf 导入到 /etc/nginx/nginx.conf 宿主机 的nginx.conf 的导入到/etc/nginx/nginx.conf 中 连接PHP的配置如下: location ~ .php$ { root /app; fastcgi_pass phpfpm:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /app$fastcgi_script_name; include fastcgi_params; }nginx配置文件如下:user root root; worker_processes auto; error_log /tmp/nginx_error.log crit; pid /tmp/nginx.pid; worker_rlimit_nofile 51200; events { use epoll; worker_connections 51200; multi_accept on; } http { include mime.types; default_type application/octet-stream; server_names_hash_bucket_size 512; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 50m; sendfile on; tcp_nopush on; keepalive_timeout 60; tcp_nodelay on; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on; server { listen 80; server_name www.bt.cn; index index.html index.htm index.php; root /app; #error_page 404 /404.html; location ~ .php$ { root /app; fastcgi_pass phpfpm:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /app$fastcgi_script_name; include fastcgi_params; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 12h; } location ~ /\. { deny all; } access_log /tmp/access.log; } }
2019年01月11日
15,550 阅读
0 评论
40 点赞
2019-01-09
PHP Warning: file_get_contents failed to open stream解决办法
file_get_contents函数在获得远程文件时提示Warning: file_get_contents failed to open stream,希望例子能够帮助到各位,希望例子能够帮助到大家。在做项目时用 file_get_contents 来获取数据,php 报错 PHP Warning: file_get_contents failed to open stream: no suitable wrapper could be found.最后用了curl来获取数据!今天百度了一下!找到了解决办法!先拷贝过来!系统:centos 6.5在错误日志中,php报的错误是Warning: file_get_contents() [function.file-get-contents]: http:// wrapper is disabled in the server configuration by allow_url_fopen=0failed to open stream: no suitable wrapper could be found此警告说服务器阻止访问远程文件,修改php.ini把allow_url_fopen = Offallow_url_include = Off改成allow_url_fopen = Onallow_url_include = On重启php-fpm或者重启web服务。如果还是无法解决 的话windows下处理方法:c:\windows\php.iniextension=php_openssl.dll 把前的;去掉,重启iis服务。linux下处理方法:/etc/php.iniextension=php_openssl.dll 把前的;去掉,重启apache服务。 如果上面问题没能解决我的问题,我们可以如下测试。 $context = stream_context_create(array('http'=>array('ignore_errors'=>true)));$contents = file_get_contents($url, FALSE, $context);可以请求时,忽略错误。可以解决警告信息
2019年01月09日
6,266 阅读
0 评论
3 点赞
2018-09-21
mongodb设置密码
mongodb安装后是无需密码Mongodb安装后自身是没有密码的,用户连接只需填写id地址,端口号,数据库名称即可安全问题只要你服务器的mongodb数据库端口开放,任何人的电脑都可以连接到你的数据库,操作修改你的mongodb数据,本人以前就遭受过入侵,深有感触。如图:黑客盗取你的数据库,然后留下一个邮箱和账号,要求你给比特币才肯归还数据库给你。。。给mongodb加密如果需要给MongoDB数据库使用安全验证,则需要用--auth开启安全性检查,只有数据库认证的用户才能执行读写操作,开户安全性检查。第一步:开机先:mongod --dbpath 存放数据库文件夹路径第二步:打开命令行窗口输入mongo,进入mongo环境 第三步:切换到 'admin' 数据库 use admin第四步:给admin设置用户密码:user: 用户名, pwd: 用户密码,roles: 用来设置用户的权限,比如读,读写 等等db.createUser({user: 'root', pwd: '123456', roles: ['root']})验证是否添加成功,'db.auth(用户名,用户密码)' 这里用db.auth('root', '123456') 如果返回 '1'表示验证成功, 如果是 '0' 表示验证失败...第5步:刚才是给root设置密码,现在要给特定的每个库设置权限,比如我这里有一个库,库名字叫做Article,这里以Article这个库为例切换到Article数据库,use Article接下来为这个库添加一个用户,并且赋予权限,db.createUser({user:'zwVic',pwd:'adgjmp123',roles: [{role:'readWrite',db:'Article'}]})})这行代码意思是 创建一个zwStar用户 给予读写权限 db表示该用户操作的数据库名OK,一切搞定,重新开机mongodb,MongoDB默认是没有开启访问控制,我们通过--auth参数重启mongod服务。mongod --dbpath 存放数据库文件夹路径 --auth一旦开启了,用户连接mongod必须指定用户名和密码。连接加密数据库xxx.db('mongodb://your name: your pwd@ ip :27017/Article');your name:为用户名your pwd:为密码总结通过加密后。连接数据库就需要账号,密码,同时阿里云或者腾讯云上也可以给服务器设置安全组增加安全性,比如27107这个端口只授权给自己访问等等....
2018年09月21日
5,064 阅读
0 评论
2 点赞
2018-09-18
PHP header()函数使用详细(301、404等错误设置)
header实现404无法找到页面 复制代码代码如下:Header("HTTP/1.1 404 Not Found"); 针对apache配置中的ErrorDocument 404 /404.php功能,把nginx配置中的 复制代码代码如下:error_page 404 /404.php; 改成 复制代码代码如下:error_page 404 = /404.php; php heager 301 复制代码代码如下: 不管页面有多少header,它会执行最后一个,不过是有条件的,例如: header('Location://www.jb51.net'); header('Location:http://www.g.cn'); header('Location:http://www.baidu.com'); 这个就会跳到百度 header('Location://www.jb51.net');echo '烈火网; header('Location:http://www.g.cn'); header('Location:http://www.baidu.com'); 这个就会跳到google 下面是关于header函数的详细使用说明 一、作用: ~~~~~~~~~ PHP只是以HTTP协议将HTML文档的标头送到浏览器,告诉浏览器具体怎么处理这个页面,至于传送的内容则需要熟悉一下HTTP协议了,与PHP无关了 传统的标头一定包含下面三种标头之一,并只能出现一次。 Location: xxxx:yyyy/zzzz Content-Type: xxxx/yyyy Status: nnn xxxxxx 二、先来了解一下HTTP协议的运作方式 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HTTP协议是基于请求/响应范式的。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为,统一资源标识符、协议版本号,后边是 MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。 它分四个过程,在HTTP协议中,服务端是指提供HTTP服务的部分,客户端是指你使用的浏览器或者下载工具等等。在通讯时,由客户端发出请求连接,服务端建立连接;然后,客户端发出HTTP请求(Request),服务端返回响应信息(Respond),由此完成一个HTTP操作。 三、HTTP协议状态码表示的意思 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1×× 保留 2×× 表示请求成功地接收 3×× 为完成请求客户需进一步细化请求 4×× 客户错误 5×× 服务器错误 四、操作实例: ~~~~~~~~~~~~~ 重定向功能,这种最常见 强制用户每次访问这个页面时获取最新资料,而不是使用存在客户端的缓存。 代码 输出状态值到浏览器,主要用于访问权限控制 比如要限制一个用户不能访问该页,则可设置状态为404,如下所示,这样浏览器就显示为即该页不存在 注意: 传统的标头一定包含下面三种标头之一,并只能出现一次。 Content-Type: xxxx/yyyy Location: xxxx:yyyy/zzzz Status: nnn xxxxxx 在新的多型标头规格 (Multipart MIME) 方可以出现二次以上。 使用范例 范例一: 本例使浏览器重定向到 PHP 的官方网站。 Header("Location: //www.jb51.net/"); exit; 范例二: 要使用者每次都能得到最新的资料,而不是 Proxy 或 cache 中的资料,可以使用下列的标头 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); 范例三: 让使用者的浏览器出现找不到档案的信息。 header("Status: 404 Not Found"); 范例四:让使用者下载档案。 header("Content-type: application/x-gzip"); header("Content-Disposition: attachment; filename=文件名"); header("Content-Description: PHP3 Generated Data"); header -- 发送一个原始 HTTP 标头说明 void header ( string string [, bool replace [, int http_response_code]] ) header() 函数用来发送一个原始 HTTP 标头。有关 HTTP 标头的更多内容见 HTTP/1.1 规范。 可选参数 replace 指明是替换掉前一条类似的标头还是增加一条相同类型的标头。默认为替换,但如果将其设为 FALSE 则可以强制发送多个同类标头。例如: 第二个可选参数 http_response_code 强制将 HTTP 响应代码设为指定值(此参数是 PHP 4.3.0 新加的)。 有两种特殊的 header 调用。第一种是标头以字符串“HTTP/”(大小写不重要)开头的,可以用来确定要发送的 HTTP 状态码。例如,如果配置了 Apache 用 PHP 来处理找不到文件的错误处理请求(使用 ErrorDocument 指令),需要确保脚本产生了正确的状态码。 注: HTTP 状态码标头行总是第一个被发送到客户端,而并不管实际的 header() 调用是否是第一个。除非 HTTP 标头已经发送出去,任何时候都可以通过用新的状态行调用 header() 函数来覆盖原先的。 HTTP状态检测(HTTP Header): 第二种特殊情况是以“Location:”标头。它不只是把这个标头发送回浏览器,它还将一个 REDIRECT(302)状态码返回给浏览器,除非之前已经发出了某个 3xx 状态码。 注: HTTP/1.1 标准需要一个绝对地址的 URI 做为 Location: 的参数, 但有一些客户端支持相对 URI。通常可以使用 $_SERVER['HTTP_HOST']、$_SERVER['PHP_SELF'] 及 dirname() 函数来自己从相对 URI 产生出绝对 URI:
2018年09月18日
5,818 阅读
0 评论
0 点赞
1
...
27
28
29