【问题标题】:Laravel SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entryLaravel SQLSTATE [23000]:违反完整性约束:1062 重复条目
【发布时间】:2014-09-16 21:11:20
【问题描述】:

我是 Laravel 的新手,这是我在 Laravel 的第一个项目。像往常一样,首先我正在开发一个完整的用户身份验证系统。我可以注册单个用户,可以发送用户验证电子邮件,然后单击它链接我可以激活一个新的用户帐户,可以登录并可以注销。但是之后每当我尝试注册另一个新用户并且单击验证链接后时,我都会遇到一个异常,

Illuminate \ Database \ QueryException
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key     'users_code_unique' (SQL: update `users` set `code` = , `active` = 1, `updated_at` = 2014-07-   25 04:26:06 where `id` = 41)

现在这是我的 route.php,

<?php

Route::get('/',array(
     'as'   =>'home',
     'uses' =>'HomeController@index'
     ));

Route::get('/signin',array(
    'as'        =>'signin',
    'uses'      =>'AccountController@signinGet'
    ));

Route::get('/signup',array(
    'as' => 'signup',
    'uses' => 'AccountController@signupGet'
    ));

/* 

/* 
/Authenticated Group
*/
 Route::group(array('before' => 'auth'),function(){
 /* 
 /Sign Out(GET)
*/

 Route::get('/signout',array
    (
        'as' => 'signout',
        'uses' => 'AccountController@signoutGet'
    ));

 });

/* 
/UnAuthenticated Group
*/
Route::group(array('before' => 'guest'),function(){

/* CSRF Protect*/
Route::group(array('before' => 'csrf'),function(){
        /*
        / Create Account(POST)
        */
        Route::post('/signup',array(
                'as'=> 'signup',
                'uses'=>'AccountController@signupPost'
            ));

        /*
        / Sign In(POST)
        */

        Route::post('/signin',array(
                'as' => 'signin-post',
                'uses' => 'AccountController@signinPost'
            ));
 });

 /* 
 / Sign In (GET) 
 */

 Route::get('/signin',array(
        'as' => 'signin',
        'uses' => 'AccountController@signinGet'
    ));

 /* 
 /Create Account(GET) 
 */
 Route::get('/signup',array(
        'as' => 'signup',
        'uses'=> 'AccountController@signupGet'
    ));
 Route::get('signup/account/activate/{code}',array(
        'as'        =>'activate-account',
        'uses'      =>'AccountController@activatePost'
    ));
 });
 ?>

这是我的 AccountController

<?php

class AccountController extends \BaseController {

public function signinGet()
{
    return View::make('account.signin');
}

public function signinPost(){

    $validator = Validator::make(Input::all(),array(
            'email' => 'required|email',
            'password' => 'required'
        ));

    if($validator->fails()){
        //redirect to the signin page
        return Redirect::route('signin')
                ->withErrors($validator)
                ->withInput();
    }else{
        //Attempt user singin

        $auth = Auth::attempt(array
            (
                'email' => Input::get('email'),
                'password' => Input::get('password'),
                'active' => 1
            ));

        if($auth){
            //Redirect To intented URL
            return Redirect::intended('/');
        }
        else
        {

            return Redirect::route('signin')
                                ->with('global','The username or password you provided is wrong or account not activated!');
        }

    }

            return Redirect::route('signin')    
                                ->with('global','There is a problem Signing You in.');
}


/**
 * Show the form for creating a new resource.
 *
 * @return Response
 */

public function signupGet()
{
    return View::make('account.signup');
}

public function signupPost()
{
    $validator = Validator::make(Input::all(), array(

        'email'             => 'required|max:255|email|unique:users',
        'username'          => 'required|min:3|unique:users',
        'password'          => 'required|min:6',
        'password_again'    =>  'required|same:password'

        )
    );

    if($validator->fails())
    {
        return Redirect::route('signup')
            ->withErrors($validator)
            ->withInput();
    }else
    {
        $email          = Input::get('email');
        $username       = Input::get('username');
        $password       = Input::get('password');

        //Activation Code
        $code = str_random(60);

        $user = User::create(array(
                    'email'     => $email,
                    'username'  => $username,
                    'password'  => Hash::make($password),
                    'code'      => $code,
                    'active'    => 0                
                    )
        );

        if($user){
            //User Activation Code Creation
            Mail::send('emails.auth.activate', array('link' => URL::route('activate-account',$code), 'username' => $username),function($message) use ($user)
                {
                    $message->to($user->email,$user->username)->subject('Activate Your Account');
                });

            return Redirect::route('signup')
                            ->with('global','Your Account has been created! We have sent you an email to activate your account.Please Check the both the Inbox and Spam Folder.');

        }

    }


    //return 'This is a Post Result';
}

public function activatePost($code){

    $user = User::where('code','=',$code)->where('active','=',0);
    if($user->count()){
        $user = $user->first();

        $user->active = 1;
        $user->code = '';
        if($user->save()){
            return Redirect::route('home')
                            ->with('global','Activated!.You can sign in now!'); 
        }
    }

    else{
        return Redirect::route('signup')
                        ->with('global','Sorry!We could not activate your acount,please try again later.');
    }
}


public function signoutGet(){

    Auth::logout();
    return Redirect::route('home');
}
}
?>

这是我创建的用户迁移文件

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration {

public function up()
{
    Schema::create('users', function(Blueprint $table)
    {
        $table->increments('id');
        $table->string('username',255)->unique();
        $table->string('email',255)->unique();
        $table->string('password',60);
        $table->string('password_temp',60);
        $table->string('code',60)->unique();
        $table->integer('active');
        $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::drop('users');
}

}
?>

这是我的 user.php

<?php

use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends Eloquent implements UserInterface, RemindableInterface {


    public function getRememberToken()
    {
        return $this->remember_token;
    }

    public function setRememberToken($value)
    {
        $this->remember_token = $value;
    }

    public function getRememberTokenName()
    {
        return 'remember_token';
    }

protected $fillable = array('email','username','password','password_temp','code','active');

use UserTrait, RemindableTrait;

/**
 * The database table used by the model.
 *
 * @var string
 */
protected $table = 'users';



/**
 * The attributes excluded from the model's JSON form.
 *
 * @var array
 */
protected $hidden = array('password', 'remember_token');

}
?>

现在有什么问题?

【问题讨论】:

  • 看起来user-&gt;code 不是唯一的。你确定是吗?尝试回显它,并与您已经在数据库中获得的内容进行比较。我曾经在 winXP 上遇到过 str_random 的问题 - 在短时间内它生成了相同的随机字符串...
  • 啊抱歉,对我来说这不是 laravels 4 str_random 而是其他一些随机化的函数,但它生成的字符串和我说的一样。
  • 那么如何解决这个问题,你有什么解决办法吗?
  • 不,我已经检查过了,实际上 str_random() 生成了唯一的字符串。
  • 这是一个猜测,但我会尝试增加 DB 模式中的字符串限制,例如。 $table-&gt;string('code',256)-&gt;unique(); 看看代码是否存储正确

标签: php authentication laravel-4


【解决方案1】:

我找到了。您已将代码列设置为唯一,但在用户单击激活链接后将其设置为空字符串。并且表中已经有一行 code='';所以它会抛出一个错误。问题就在这里(activatePost):

$user->code = '';

所以要么不要清空它,将其设置为其他值,要么将 db 列设置为不唯一。

我会留下代码而不清空它,另外我会检查用户是否被激活 - 一个简单的 if 在 activatePost 中。也许不仅根据代码验证用户,而且在链接中使用哈希 id 验证用户是个好主意。

【讨论】:

    【解决方案2】:

    确保您的code 字段为nullable,然后将其值设置为空字符串,而不是将其设置为空:

    $code = null;
    

    然后您将能够将其保存为 NULL (MySQL),同时它仍然是唯一的。


    也改这个:

     $user = User::where('code','=',$code)->where('active','=',0);
       if($user->count()){
         $user = $user->first();
    

    收件人:

     $user = User::where('code','=',$code)->where('active','=',0)->first();
       if(count($user)){
    

    你不需要调用 db 两次,只要检查返回的结果是否不为空(count 可以),这意味着它返回了一个User 对象。

    【讨论】:

    • 我有同样的问题,我做了 $primarykey = '' 并且它工作了,然后我把 $primarykey 放回 $primarykey = null
    【解决方案3】:

    您需要做一些事情来改进您的代码。但是,当您将列设置为唯一并尝试将相同的数据重新插入另一行时,通常会发生重复条目。最令人困惑的是当您检查表格并发现该列为空时。哎呀!当一列设置为唯一且为空时,这意味着没有其他列可以包含空数据。

    简单来说,列的形式不能重复,无论是空的还是带数据的。

    【讨论】:

      【解决方案4】:

      您的问题可以使用验证器来检查。只需像这样使用:

      use Validator;
      use Request;
      //...
      //unique will pre check the key code weather if unique in tbl_name
      public function yourfunc(Request $request) {
          // set the rules to check
          $rules = ['code'=>'required|unique:tbl_name'];
          $validator = Validator::make($request->all(), $rules);
          if ($validator->fails()) {
             // handler errors
             $erros = $validator->errors();
          }
          //... everything is ok here
      }
      

      您可以通过laravel validation了解更多信息

      【讨论】:

      • 插入数据时唯一值问题最简单最准确的解决方案
      猜你喜欢
      • 2016-01-16
      • 2021-10-11
      • 2016-05-23
      • 2013-04-22
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 2021-05-30
      • 1970-01-01
      相关资源
      最近更新 更多