찾다
백엔드 개발PHP 튜토리얼PHP的Yii框架使用中的一些错误解决方法与建议,yii框架_PHP教程

PHP的Yii框架使用中的一些错误解决方法与建议,yii框架

 此文意在记录 Yii 开发过程中的小问题解决方案,不全面,不权威,不是教程。自己写过,觉得可以解决问题,以后也可能用上,就记记吧。

    1. Yii 中 Js 和 Css 文件的引入。
    我们就从最简单的问题开始吧,说起来也不是问题,只是语法罢了。假设我们的 js 文件都放在和 protected 同一层的 js 文件夹里,css 文件都放在和 protected 同一层的 css 文件夹里,好吧,规范就是这样的...那我们可以在对应的 view 界面按下面这样写,css 和 js 函数的参数是不同的哦...(之前因为这个调了一个小时..)
    注册 js 文件的第二个参数是 js 所放的位置,可选三个:CClientScript::POS_HEAD 放在 Head 部分  CClientScript::POS_BEGIN  放在 Body 开始处  CClientScript::POS_END  放在 Body 结束处,没有特别要求就不用填了...注册 Css 文件的第二个参数是 media,,有兴趣的同学点这里,目前还是默认就好...
    对于 Jquery 这样的 js ,用 registerCoreScript 不会造成莫名奇妙的错误...

//注册 js 文件 
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl.'/js/project1.js',CClientScript::POS_HEAD); 
//注册 css 文件 
Yii::app()->clientScript->registerCssFile(Yii::app()->baseUrl.'/css/project1.css'); 
//注册 Jquery 文件 
Yii::app()->clientScript->registerCoreScript('jquery'); 

    2. Yii isNewRecord 修复
    Yii 的 Model 的 isNewRecord 属性是很好用的,可以根据这个属性进行分情况讨论。但是,假如我们开启了事务机制或是其他情况,造成数据插入后又被回滚了,这时数据库里没有该条记录,但是 isNewRecord 是 flase,即认为已经不是新纪录了。解决方法是用主键去访问数据库,判断究竟是不是新纪录,而我们在用到这个属性之前要先按下面处理一下。以下 Model 是 Post,主键是 id:

if(!$model->isNewRecord) 
{ 
  $db_exist = Post::model()->findByPk($model->id); 
  if($db_exist == NULL) 
    $model->isNewRecord = true; 
} 


    3.Yii 生成 隐藏输入域
    虽然自己写一个输入域很容易(不就是 display:none 嘛),但是有时架不住需要按照 Yii 的表单代码格式呀,反正就一句话...

<&#63;php echo $form->hiddenField($model,'name'); &#63;> 
<&#63;php if($model->isNewRecord) echo $form->hiddenField($model,'path',array('size'=>60,'maxlength'=>128,'id'=>'path1')); &#63;> 

    4. Yii 生成下拉菜单
     很多时候我们在 form 里需要一个下拉菜单,这时候 Chtml 的 listdata 就很好用的。假如我们数据库里的字段只有很少的可能,比如 0 和 1,可以按下面写:

echo $form->dropDownList($model,'is_marry',array('0'=>'否','1'=>'是')); 

    这时候,你看到的就是 是 和 否 的下拉菜单,选择 '是' 提交的时候这个字段填的就是 1 ,'否' 就是 0 。当然,经常不只这么简单,我们可以在 Model 里面添加一个函数用于生成下拉菜单的数组,然后在 view 里去调用就行了。这个函数的数据可以自己写的,或者在数据库查找得来的。下面用了 listdata, 具体意思是以 model 中 id 为 键, name 为值。

/* 写在 model 里 */ 
public function getUserOptions() 
{ 
  $models = User::model()->findAll(); 
  $models = User::model()->findAllByAttributes(array('is_regeister'=>'1')); 
  return CHtml::listdata($models, 'id', 'name'); 
} 
 
/* 写在 view 的界面里 */ 
echo $form->dropDownList($model,'user_id',User::model()->getUserOptions()); 


5.Yii  开启事务机制
    在你同时保存几条记录到数据库时,你可能很有必要开启事务机制。Yii 开启事务机制很容易,只要三句话就够了。

/*开启事务机制*/ 
$transaction = Yii::app()->db->beginTransaction(); 
try 
{ 
  /* 成功则 commit */ 
  $transaction->commit(); 
} 
catch(Exception $e) 
{ 
  $transaction->rollBack(); 
} 

    比较完整的像这样:

if($_POST['ModelA']) 
{ 
  /*开启事务机制*/ 
  $transaction = Yii::app()->db->beginTransaction(); 
  try 
  { 
    /*此处省略一堆逻辑*/ 
    $modelA->save(); 
    $modelB->save(); 
 
    /* 成功则 commit */ 
    $transaction->commit(); 
    $this->redirect(array('view','id'=>$model->id)); 
  } 
  catch(Exception $e) 
  { 
    $transaction->rollBack(); 
  } 
} 

    不过我一般会像下面这样,有什么好处请自行体会...

if($_POST['ModelA']) 
{ 
  /*开启事务机制*/ 
  $transaction = Yii::app()->db->beginTransaction(); 
  try 
  { 
    $validated = true; 
 
    /*此处省略一堆逻辑*/ 
    $valid = $modelA->save(); 
    $validated = $valid & $validated; 
 
    /*此处继续省略一堆逻辑*/ 
    $valid = $modelB->save(); 
    $validated = $valid & $validated; 
 
    /* 成功则 commit */ 
    if($validated) 
    { 
      $transaction->commit(); 
      $this->redirect(array('view','id'=>$model->id)); 
    } 
    else 
    { 
      /*不成功即回滚 */ 
      $transaction->rollBack(); 
    } 
  } 
  catch(Exception $e) 
  { 
    $transaction->rollBack(); 
  } 
} 

6.关联表查询相同字段出错。
    有时候我们建了两个表,但是两个表有相同的字段,在用 CDbCriteria 进行 with 关联查询搜索时候,如果没有进行额外设置,那会出现查询错误,大概的意思就是 Mysql 语句模糊。这时候,我们在主表设置一个别名就好了,然后查询相关字段的时候注意把 名字加上就行。
    比如:两个 Model, Post 和 User,都有一个 id, 在 我们可以像下面这样写:

$criteria=new CDbCriteria; 
 
$criteria->alias = "post"; 
 
$criteria->with = array('user'); 
 
$criteria->compare('post.id',$Post->id,true); 
 
$model = Post::model()->find($criteria); 

7.文件上传
    说起来这个不算是 Yii 的,基本都是原生的 HTML 和 PHP,懒得分,就直接放这里吧。
    下面是 HTML,action 改为你自己的 url, id 和 name 也由你自己定义。

<form action="your url" method='post' enctype="multipart/form-data" id='fileform'> 
  <p style='display:inline-block'>文件上传  </p><input id='file1' name='file1' type='file' ></input> 
  <br /> 
  <input type='submit' value='上传'> 
</form> 

    这是服务器端接收并保存文件的代码,文件最后保存到了 attached 文件夹的 file 文件夹里:

if(isset($_FILES['file1'])) 
{ 
  $xlsfile = $_FILES['file1']; 
  $tmp_name = $xlsfile['tmp_name']; 
  /*获取文件名*/ 
  $file_name = basename($xlsfile_name); 
 
  if($xlsfile['error'] > 0) 
  { 
    echo "文件上传出错!请重试。<br />"; 
    exit; 
  } 
  else 
  { 
    if(file_exists("attached/tmp/".$file_name)) 
      echo "文件已存在!本次不予保存!"; 
    else 
    { 
      if(!is_dir("attached/tmp/")) 
      { 
        /*新建文件夹,默认权限 777, true 意味着可以递归从创建*/ 
        if(!mkdir("attached/tmp/",0777,true)) 
        { 
          echo "找不到 attached/tmp 文件夹,且创建失败!<br />"; 
          exit; 
        } 
      } 
 
      /*这个函数仅用于上传文件的移动*/ 
      move_uploaded_file($tmp_name,"attached/tmp/".$file_name); 
    } 
  } 
} 

    下面是把已存在的文件从 old_file 路径移到 attached/file 里面的当前日期文件夹。这里的移动用 rename

/*创建文件夹*/ 
$date = date('Y-m-d',time()); 
$date = str_replace('-',"",$date); 
$dir = "attached/file/".$date.'/'; 
if(!is_dir($dir)) 
{ 
  if(!mkdir($dir,0777,true)) 
  { 
    exit('无法创建文件夹!'); 
  } 
} 
 
/*移动文件*/ 
$file_name = basename($old_file); 
$finish = rename($old_file,$dir.$file_name); 
if(!$finish) 
{ 
  exit('无法移动文件!'); 
} 

8.YIi 场景与安全字段
    查看当前 Model 场景:

var_dump($model->scenario); 

     查看场景的安全字段。安全字段的意思是说这些数据由用户提交的时候不会被 Yii 过滤掉。有次发现网页提交上来的东西有些有有些没,调了很久才知道在那个场景下部分被过滤了。

$arr = $model->getSafeAttributeNames($model->scenario); 
var_dump($arr); 

    强制赋值避免 rule 规则过滤字段。用 setAttributes 可以强制取消 Yii 的安全过滤,只要第二个参数赋值为 false 就好。但是这也只能对这个 Model 生成时就拥有的字段生效,如果要对包括自己定义的所有字段不过滤,还是要定义场景然后在 rule 里指定安全字段比较好。

if(isset($_GET['Po'])) 
  $model->setAttributes($_GET['Post'],false); 

检查日期格式合法性
    有时我们需要检验用户填写的日期是否合法,可以用下面的函数。

function checkDatetime($dateStr, $format = "Y-m-d H:i:s") 
{ 
  $time = strtotime($dateStr); 
  $checkDate = date($format, $time); 
 
  return $checkDate == $dateStr; 
} 

Yii 渲染多个 model
    相信新手都有疑惑,_form 里面的表单都是渲染一个 model 然后提交给 controller 保存数据的,如果想要渲染多个 model 怎么办呢?
    下面,我们假设有两个 model 类,分别叫做 Person 和 Addr,我们想要做的是在一个 Person 的 _form 里再渲染几个 Addr 的 model ,意思是一个人可以有几个地址。基本思路其实还是很简单,就是你在 controller 里定义要渲染的 model 然后传给 view 界面,最后依然在 controller 里接收 Post 过来的数据。主要是写法问题而已,我相信下面大家都能看懂,有疑问的童鞋再留言好了。

//在 controller 里面 
 
$model=new Person; 
/* $addrs 存储 Addr model 的数组,放几个你就看着办吧*/ 
$addrs = array(); 
 
if(isset($_POST['Person'])) 
{ 
  $model->attributes = $_POST['Person']; 
  /*此处省略一堆逻辑*/ 
  foreach($_POST['Addr'] as $one_addr) 
  { 
    $addr = new Addr(); 
    $addr->attributes = $one_addr; 
    /*此处省略另一堆逻辑*/ 
  } 
} 
 
$this->render('create',array( 
  'model'=>$model, 
  'addrs' => $addrs, 
)); 
 
 
//在 view 里面 
 
/*可以循环输出你的多个 model */ 
$num = count($addrs); 
for($i = 0;$i < $num;++$i) 
{ 
  echo $form->labelEx($addrs[$i],"[{$i}]postcode"); 
  echo $form->textField($addrs[$i],"[{$i}]postcode",array('size'=>10,'maxlength'=>10)); 
  ...; 
} 
 
/*也可以通过数字指定输出某个 model */ 
echo $form->labelEx($addrs[0],"[0]postcode"); 
echo $form->textField($addrs[0],"[0]postcode",array('size'=>10,'maxlength'=>10)); 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1049138.htmlTechArticlePHP的Yii框架使用中的一些错误解决方法与建议,yii框架 此文意在记录 Yii 开发过程中的小问题解决方案,不全面,不权威,不是教程。自己...
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP의 의존성 주입 : 일반적인 함정을 피하십시오PHP의 의존성 주입 : 일반적인 함정을 피하십시오May 16, 2025 am 12:17 AM

의존성 (di) inphpenhancescodeflexibility 및 testability는 decouplingdependencycreation fromusage.toimplementDieffectically : 1) addicontainersjudicuelyToavoidover-Engineering.2) indhe. 3) adhe

PHP 웹 사이트 속도를 높이는 방법 : 성능 조정PHP 웹 사이트 속도를 높이는 방법 : 성능 조정May 16, 2025 am 12:12 AM

toimproveyourphpwebsite의 성능, UsetheseStrospations : 1) ubstractOpCodeCachingWithOpCaceToSpeedUpscriptScriptIngretation.2) 최적화 된 AabaseQueriesBysElectingOnlynecessaryFields.3) UsecachingsystemsLikeredSormcedUcedUcedUcedALOW

PHP와 함께 대량 이메일 보내기 : 가능합니까?PHP와 함께 대량 이메일 보내기 : 가능합니까?May 16, 2025 am 12:10 AM

예, itispossibletosendmassemailswithphp.1) uselibraries -lifephpmailerorswiftmailerforfficialemailsending.2) emubledelaysbetemailstoavoidspamflags.3) personalizeemailsingdynamiccontenttoimproveengement.4) usequeuesystemslikerbitmbitmquredisb

PHP에서 의존성 주입의 목적은 무엇입니까?PHP에서 의존성 주입의 목적은 무엇입니까?May 16, 2025 am 12:10 AM

의존성 (di) inphpisadesignpatternthatachievesinversionofcontrol (ioc) by ancelociestobeinjectedintoclasses, 향상 모듈 성, 테스트 가능성 및 flexibility.didecouplesssclassessfromspecificimplementations, codemoremanageableandadapt

PHP를 사용하여 이메일을 보내는 방법?PHP를 사용하여 이메일을 보내는 방법?May 16, 2025 am 12:03 AM

PHP를 사용하여 이메일을 보내는 가장 좋은 방법은 다음과 같습니다. 1. 기본 전송에 Php 's Mail () 함수를 사용합니다. 2. phpmailer 라이브러리를 사용하여 더 복잡한 HTML 메일을 보내십시오. 3. Sendgrid와 같은 트랜잭션 메일 서비스를 사용하여 신뢰성 및 분석 기능을 향상시킵니다. 이러한 방법을 사용하면 이메일이받은 편지함에 도달 할뿐만 아니라 수신자를 유치 할 수 있습니다.

PHP 다차원 배열에서 총 요소 수를 계산하는 방법은 무엇입니까?PHP 다차원 배열에서 총 요소 수를 계산하는 방법은 무엇입니까?May 15, 2025 pm 09:00 PM

PHP 다차원 어레이에서 총 요소 수를 계산하는 것은 재귀 적 또는 반복적 인 방법을 사용하여 수행 할 수 있습니다. 1. 재귀 방법은 배열을 가로 지르고 중첩 배열을 재귀 적으로 처리함으로써 계산됩니다. 2. 반복 방법은 스택을 사용하여 깊이 문제를 피하기 위해 재귀를 시뮬레이션합니다. 3. Array_Walk_Recursive 함수도 구현할 수 있지만 수동 계산이 필요합니다.

PHP에서 DO-While 루프의 특성은 무엇입니까?PHP에서 DO-While 루프의 특성은 무엇입니까?May 15, 2025 pm 08:57 PM

PHP에서, do-while 루프의 특성은 루프 본체가 적어도 한 번 실행되도록하고 조건에 따라 루프를 계속할지 여부를 결정하는 것입니다. 1) 조건부 점검 전에 루프 본체를 실행하며, 사용자 입력 확인 및 메뉴 시스템과 같이 작업을 적어도 한 번 수행 해야하는 시나리오에 적합합니다. 2) 그러나, do-while 루프의 구문은 초보자들 사이에서 혼란을 야기 할 수 있으며 불필요한 성능 오버 헤드를 추가 할 수 있습니다.

PHP에서 문자열을 해시하는 방법은 무엇입니까?PHP에서 문자열을 해시하는 방법은 무엇입니까?May 15, 2025 pm 08:54 PM

PHP의 효율적인 해싱 스트링은 다음 방법을 사용할 수 있습니다. 1. 빠른 해싱에 MD5 기능을 사용하지만 비밀번호 저장에는 적합하지 않습니다. 2. SHA256 기능을 사용하여 보안을 향상시킵니다. 3. Password_hash 함수를 사용하여 비밀번호를 처리하여 최고 보안과 편의성을 제공하십시오.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)