Fecmall

第 2 位会员

会员
个人信息
  • 加入于 2017-05-31 17:38:45
  • 城市 Qingdao
  • GitHub https://github.com/fecshop
  • 最后登录时间 10天前
  • 签名 净化自己,潜心编码
个人简介
Terry,Fecmall开源产品作者,12年电商经验一线程序员开发者,擅长规划产品,架构设计。
个人成就
  • 发表文章次数 744
  • 发布回复次数 5760
  • 个人主页浏览次数 683
paypal支付问题7年前

你的网站地址发我一下,操作看一下

Yii2 user组件 $identity->id 取出来是字符串的问题 - 刨根问底7年前

我机器是64位, 输出了PHP_INT_SIZE,值为8, 所以没有问题。

Yii2 user组件 $identity->id 取出来是字符串的问题 - 刨根问底7年前

哈哈,释然了,你的机器是32位的吧?

PHP_INT_SIZE:表示整数integer值的字长

PHP_INT_MAX:表示整数integer值的最大值

注:

输出下32位中PHP_INT_SIZE:4,PHP_INT_MAX:2147483647
输出下64位中PHP_INT_SIZE:8,PHP_INT_MAX:9223372036854775807

yii\db\Schema

/**
     * Extracts the PHP type from abstract DB type.
     * @param ColumnSchema $column the column schema information
     * @return string PHP type name
     */
    protected function getColumnPhpType($column)
    {
        static $typeMap = [
            // abstract type => php type
            self::TYPE_TINYINT => 'integer',
            self::TYPE_SMALLINT => 'integer',
            self::TYPE_INTEGER => 'integer',
            self::TYPE_BIGINT => 'integer',
            self::TYPE_BOOLEAN => 'boolean',
            self::TYPE_FLOAT => 'double',
            self::TYPE_DOUBLE => 'double',
            self::TYPE_BINARY => 'resource',
            self::TYPE_JSON => 'array',
        ];
        if (isset($typeMap[$column->type])) {
            if ($column->type === 'bigint') {
                return PHP_INT_SIZE === 8 && !$column->unsigned ? 'integer' : 'string';
            } elseif ($column->type === 'integer') {
                return PHP_INT_SIZE === 4 && $column->unsigned ? 'string' : 'integer';
            }

            return $typeMap[$column->type];
        }

        return 'string';
    }

到这里问题的根找到了,赞~,欣赏你刨根问底的劲。

Yii2 user组件 $identity->id 取出来是字符串的问题 - 刨根问底7年前

@myred08 #1楼 你mysql什么版本?我的加了,没有问题。

算了这个根据自己情况弄吧,我这里就先这样记录一下

产品添加Add to Favorites 失败。7年前

你这个可以整理个文章了

产品添加Add to Favorites 失败。7年前

安装fecshop,这个是有的

https://github.com/fecshop/yii2_fecshop/blob/master/migrations/mysqldb/m170228_072156_fecshop_tables.php

CREATE TABLE IF NOT EXISTS `customer` (
			  `id` int(20) unsigned NOT NULL AUTO_INCREMENT,
			  `password_hash` varchar(80) DEFAULT NULL COMMENT '密码',
			  `password_reset_token` varchar(60) DEFAULT NULL COMMENT '密码token',
			  `email` varchar(60) DEFAULT NULL COMMENT '邮箱',
			  `firstname` varchar(100) DEFAULT NULL,
			  `lastname` varchar(100) DEFAULT NULL,
			  `is_subscribed` int(5) NOT NULL DEFAULT '2' COMMENT '1代表订阅,2代表不订阅邮件',
			  `auth_key` varchar(60) DEFAULT NULL,
			  `status` int(5) DEFAULT NULL COMMENT '状态',
			  `created_at` int(18) DEFAULT NULL COMMENT '创建时间',
			  `updated_at` int(18) DEFAULT NULL COMMENT '更新时间',
			  `password` varchar(50) DEFAULT NULL COMMENT '密码',
			  `access_token` varchar(60) DEFAULT NULL,
			  `birth_date` datetime DEFAULT NULL COMMENT '出生日期',
			  `favorite_product_count` int(15) NOT NULL DEFAULT '0' COMMENT '用户收藏的产品的总数',
			  `type` varchar(35) DEFAULT 'default' COMMENT '默认为default,如果是第三方登录,譬如google账号登录注册,那么这里的值为google',
			  PRIMARY KEY (`id`),
			  KEY `email` (`email`),
			  UNIQUE KEY `access_token` (`access_token`)
			) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
			", "

用postman调试server接口(后续待更新)7年前

http://www.fecshop.com/doc/fecshop-guide/develop/cn-1.0/guide-fecshop-vue-config.html

多看文档,多联系,最好把vue端安装一下对照vue的代码,会理解的更好

接口这块是麻烦一些。

用postman调试server接口(后续待更新)7年前

postman添加request header

关于appserver,更详细的,你可以看一下vue的代码实现。

用postman调试server接口(后续待更新)7年前

对于 文档里面说的 fecshop-lang fecshop-currency

这个需要从vue localstorage中取,获取产品信息,name就会是相应的语言,价格是相应货币的价格

但是,不发送这些request header信息,也可以获取数据,不过语言是默认语言,货币是默认货币

用postman调试server接口(后续待更新)7年前

给你演示一下这个文档,获取分类信息:http://www.fecshop.com/doc/fecshop-guide/develop/cn-1.0/guide-fecshop-server-api-category.html

1.请求的url为:http://fecshop.appserver.fancyecommerce.com/catalog/category/index?categoryId=57bea0d3f656f2ec1f3bf56e

这样就出来结果了,对于出来的结果,查看一下response header里面的信息

vue端,第一次访问,是没有fecshop-uuid的,通过第一次的请求,response header里面会返回fecshop-uuid, 这个是对这个用于的唯一标示,类似于session的key,因此,后面的所有的请求,vue端都需要把fecshop-uuid放到request headers中。

为什么要这样做呢?因为vue这种纯接口化的入口,也需要存储一些类似session的东西,譬如无登录购物车,因此后面用户发送的请求在request headers都有fecshop-uuid,服务端就会从redis取出来这个uuid相应的数据,譬如上面说的购物车数据。

因此你后面的请求,对于像获取分类这种无状态的api,不加fecshop-uuid 是没有影响的(建议都加上,一致化),照样可以获取分类,但是对于获取购物车信息这种,如果不加,就会获取不到

产品添加Add to Favorites 失败。7年前

@myred08 #35楼 pdo是这样的,Yii2的AR查询,在没有加入asArray()的情况下,会给进行类型转换的。

但是你那个不正常,不知道为什么 findOne函数,是会给类型转换 的,不知道你的为什么不行~

产品添加Add to Favorites 失败。7年前

@myred08 #33楼 你也很xx,喜欢刨根问底。

产品添加Add to Favorites 失败。7年前

其实到这里已经说明问题,你的Yii2框架,为什么findOne()函数出来的,为什么id是string,但是 created_at status是int呢?

我也搞不明白,不过我可以继续说一下,下面是代码追踪

AR: yii/db/ActiveRecord.php 继承于 yii/db/BaseActiveRecord

在这个文件可以看到:findOne函数

/**
     * {@inheritdoc}
     * @return static|null ActiveRecord instance matching the condition, or `null` if nothing matches.
     */
    public static function findOne($condition)
    {
        return static::findByCondition($condition)->one();
    }

static::findByCondition 函数在 yii/db/ActiveRecord.php

/**
     * Finds ActiveRecord instance(s) by the given condition.
     * This method is internally called by [[findOne()]] and [[findAll()]].
     * @param mixed $condition please refer to [[findOne()]] for the explanation of this parameter
     * @return ActiveQueryInterface the newly created [[ActiveQueryInterface|ActiveQuery]] instance.
     * @throws InvalidConfigException if there is no primary key defined
     * @internal
     */
    protected static function findByCondition($condition)
    {
        $query = static::find();

        if (!ArrayHelper::isAssociative($condition)) {
            // query by primary key
            $primaryKey = static::primaryKey();
            if (isset($primaryKey[0])) {
                $pk = $primaryKey[0];
                if (!empty($query->join) || !empty($query->joinWith)) {
                    $pk = static::tableName() . '.' . $pk;
                }
                $condition = [$pk => $condition];
            } else {
                throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
            }
        }

        return $query->andWhere($condition);
    }

后面您自己慢慢玩吧

不过,你可以通过下面的方法来处理一下int字段,进来解决这个问题

你更改一下fecshop的代码,将@fecshop/models/mysqldb/Customer.php 的方法

public static function findIdentity($id)
    {
        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
    }

更改为:

public static function findIdentity($id)
    {
        $result = static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
		$result['id'] = (int)$result['id'];
		return $result;
    }

这样应该就可以了。进行int转化一下,如果这样没有问题,可以看到产品收藏,那说明修改好了。

当然这种直接修改源码是不好的,最好用重写的方式,下面详细和你说一下(看在你这么钻研的态度上)

1.打开@appfront/config/fecshop_local.php , return数组中加入配置

return [
    'modules'  => $modules,
    'services' => $services,
    'components' => [ 
        'user' => [
            'identityClass'    => 'appfront\local\local_models\mysqldb\Customer',
        ],
    ],
];

然后新建文件 @appfront\local\local_models\mysqldb\Customer.php

这个class继承于 fecshop\models\mysqldb\Customer, 然后覆盖方法 findIdentity(),也就是将上面的函数赋值进去

<?php
/**
 * FecShop file.
 *
 * @link http://www.fecshop.com/
 * @copyright Copyright (c) 2016 FecShop Software LLC
 * @license http://www.fecshop.com/license/
 */

namespace appfront\local\local_models\mysqldb;

class Customer extends \fecshop\models\mysqldb\Customer
{

	public static function findIdentity($id)
    {
        $result = static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
		$result['id'] = (int)$result['id'];
		return $result;
    }




}

这样重写就完成了

产品添加Add to Favorites 失败。7年前

对于Yii2的 findOne() 方法,是会转换相应的数据类型的,你先打印看看

@fecshop\models\mysqldb\Customer 的 函数 findIdentity($id) 返回值 是int还是string

产品添加Add to Favorites 失败。7年前

我去 yii/web/User.php 看了一下代码

protected function renewAuthStatus()
    {
        $session = Yii::$app->getSession();
        $id = $session->getHasSessionId() || $session->getIsActive() ? $session->get($this->idParam) : null;

        if ($id === null) {
            $identity = null;
        } else {
            /* @var $class IdentityInterface */
            $class = $this->identityClass;
            $identity = $class::findIdentity($id);
        }

$identity = $class::findIdentity($id); 这个代码出来的 $identity

通过代码: $class = $this->identityClass;可以知道 $class 就是配置中的 identityClass

@fecshop/app/appfront/config/appfront.php 可以看到配置

'user' => [
            'class'            => 'fecshop\yii\web\User',
            'identityClass'    => 'fecshop\models\mysqldb\Customer',

因此,上面的 $this->identityClass 就是 'fecshop\models\mysqldb\Customer'

因此打这个文件,查看

/**
     * @property $id | Int , 用户id
     * 通过id 找到identity(状态有效)
     */
    public static function findIdentity($id)
    {
        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
    }

是这个函数

因此你可以这样改改,打印一下

 public static function findIdentity($id)
    {
        $re = static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
        var_dump($re);
        exit;
        return $re
        
    }

看看这个里面的id是字符串还是int

产品添加Add to Favorites 失败。7年前

@myred08 #26楼 是pdo。

对于Yii2

如果取数据使用的是 AR::find()->asArray()->where()->all() 取出来的int类型是字符串的

如果取数据使用的 AR::find()->where()->all() 取出来的int类型,是int类型、

也就是说,如果存在asArray(),yii2的AR不会进行类型转换。

你查看一下代码是否有asArray()

产品添加Add to Favorites 失败。7年前
public function switchIdentity($identity, $duration = 0)
    {
        $this->setIdentity($identity);

        if (!$this->enableSession) {
            return;
        }

        /* Ensure any existing identity cookies are removed. */
        if ($this->enableAutoLogin && ($this->autoRenewCookie || $identity === null)) {
            $this->removeIdentityCookie();
        }

        $session = Yii::$app->getSession();
        if (!YII_ENV_TEST) {
            $session->regenerateID(true);
        }
        $session->remove($this->idParam);
        $session->remove($this->authTimeoutParam);

        if ($identity) {
            $session->set($this->idParam, $identity->getId());
            if ($this->authTimeout !== null) {
                $session->set($this->authTimeoutParam, time() + $this->authTimeout);
            }
            if ($this->absoluteAuthTimeout !== null) {
                $session->set($this->absoluteAuthTimeoutParam, time() + $this->absoluteAuthTimeout);
            }
            if ($this->enableAutoLogin && $duration > 0) {
                $this->sendIdentityCookie($identity, $duration);
            }
        }

        // regenerate CSRF token
        Yii::$app->getRequest()->getCsrfToken(true);
    }

$session->set($this->idParam, $identity->getId());: 这个是set 当前用户的id的值, 你调试一下,看看到底是哪里出现的问题(可能不止这一个地方set,你自己细细看看吧)

您自己慢慢研究下吧,我也只能说这么多了,您自己调试打印看看输出,导致这个问题的根源在什么地方。

产品添加Add to Favorites 失败。7年前

@myred08 #21楼 上面给予的代码有的

你可以用Yii::$app->session 自己测试一下,set一个int类型,取出来看看是否还是int

产品添加Add to Favorites 失败。7年前

你先把redis当成黑盒,你看看session,set的时候,set的值是字符串还是int,如果set的值是int,取出来是字符串,说明redis有问题,你的redis版本是多少,是不是版本过低?

Your Site Analytics