Drupal 7 开发内部培训资料, 分头诗人

form表单写入mysql问题及数据库关联问题

赞成!
0
否决!

看完诗人的传统留言板模块,也就自写了一个提交表单,表单写入到数据库subscribe表里面。

目的是实现:想看杂志者,需提交详情这样咯

比如:


 $form['job_title'] = array(
    '#type' => 'select',
    '#title' => 'Job Title:',
	'#options' => drupal_map_assoc(array('CEO', t('COO'), t('CTO'),t('CFO'), t('CCO'))),
    '#required' => TRUE,
  );

 

然后就是:

  db_insert('subscribe')
    ->fields(array( 'job_title' => $form_state['values']['job_title'],))->execute();

按照诗人这代码: Job title下拉框里,选啥就把啥写入数据库subscribe表job_title 字段里咯

1. 有办法实现选CEO的 写入数据库是001 选COO 的写入数据库是002, 选CTO 的写入数据库003

    然后有个关联的表,外键 003 是CTO, 002是COO, 001 是CEO 么。这样比较方便多语言啊。

2. 然后就是国家的话,那个下拉框选项我不是要copy到手残废。把200多个国家写在option 里面么?

3. 然后我让没登陆者不能到subscribe这个页面,就重写了subscribe这一页page--subscribe.tpl.php 扔 主题模板里面了。

    在那里做了个判断:没登陆者直接跳到登陆界面。有什么友好点的措施么,或弹出javascript窗口温馨提示一下:请登陆啊亲~

    还有这个判断可以写到subscribe module 里面么?

判断代码:

<?php
if(!user_is_logged_in()){
	header('location:/user/login');
    exit;
} 
?>

4. 要实现填过详细信息的人,就不需要填第二次了

所以我global 了 $user; 又在表单里增加了一个hidden

      $form['user_name'] = array(
    '#type' => 'hidden',
    '#title' => 'User Name:',
	'#default_value' => $user->name,
  );

目的是把填过详细表单的user 的名字先记下来,等以后它还想下载就可以做一个判断,如果发现subscribe 表里面user_name字段有和user 表里面name字段同名的,证明这个user 以前提交过详情,可以直接下载,不需要再填这个表单了。 若没有发现有相同名字说明这个user 没提交过详情,需要填表。想问问诗人或其他高手,有比较简便的方法实现么?

 

谢谢耐心看完。确实好多。

感谢!

另外问一下还是mysql的数据库外键关联之类的:

这个关联是怎么设置,或实现的呢,记得之前写php是 比如:

某表type 字段里 有001, 002,003

子表type_detail “001”对应“被子”     002 对应 “手机”       “003” 对应“电脑”

要找这个东西是什么,往往先找 type 表,发现那个东西是001 然后在找type_detail 表, 才找出001 是代表被子。

感觉这样数据库并没有关联,而是通过查询让他们关联在一起而已。

不好意思水平实在很水,不知道是不是这样。

 

望指导。再次感谢!

 

3 个回答

赞成!
0
否决!

非常详细的,很不错

1. 有办法实现选CEO的 写入数据库是001 选COO 的写入数据库是002, 选CTO 的写入数据库003,然后有个关联的表,外键 003 是CTO, 002是COO, 001 是CEO 么?

 '#options' => drupal_map_assoc(array('CEO', t('COO'), t('CTO'),t('CFO'), t('CCO'))),

这段中,有发现drupal_map_assoc() 方法吗? 这个方法是为了实现label 跟 value 一样,如果你想这两个值显示不一样,那就取消drupal_map_assoc():

$form['job_title'] = array(
    '#type' => 'select',
    '#title' => 'Job Title:',
    '#options' => array(001 => ('CEO'), 002 => t('COO'), 003 => t('CTO'), 004=> t('CFO'), 005 => t('CCO')),
    '#required' => TRUE,
  );

 

2. 然后就是国家的话,那个下拉框选项我不是要copy到手残废。把200多个国家写在option 里面么?

请看看 Chosen 模块,对于下拉列表,非常方便。用户体验非常好。

 

3. 然后我让没登陆者不能到subscribe这个页面,就重写了subscribe这一页page--subscribe.tpl.php 扔 主题模板里面了。
    在那里做了个判断:没登陆者直接跳到登陆界面。有什么友好点的措施么,或弹出javascript窗口温馨提示一下:请登陆啊亲~
    还有这个判断可以写到subscribe module 里面么?

有很多种方法

方法1:直接修改page--subscribe.tpl.php

<?php if ($user->uid) : ?>
<?php print render($page['content']); ?>
<?php else : ?>
      <div id="front">     
    <?php
     $block = block_load('user', 'login');
     $signup = drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));
     print $signup;
    ?>
     <?php endif; ?>

或者:

<?php if ($user->uid) : ?>
<?php print render($page['content']); ?>
<?php else : ?>
      <!--这里写跳转代码,跳转到xxx.com/user-->
     <?php endif; ?>

方法2:在subscribe模块中写权限

hook_menu 中有一项权限选择可以在这里通过权限控制。如果没有权限,就drupal_set_message, 或者跳转到xxx.com/user

 

4. 要实现填过详细信息的人,就不需要填第二次了?

你的方法,也是我的方法,这个也有一个例子,就是drupal commerce 组件系列中有一个 commerce addressbook。它是为了让用户能重用结账地址。基本也是用这个方式实现,如果你有想参考下,可以安装这个模块试一下。

 

5. 如何做关联表?

这个其实看drupal core 的表就能看出,举例,content type 新建了一个字段假使叫image,它其实在数据库中,这个image并非以字段保存,而是直接生成一个表 field_data_field_image,当你添加数据的时候,他会直接在这个表存资料。如:

上图是field_data_field_image表,有看到框框俩个字段吗?第一个字段 entity_id,就是关联 node表的 nid的,而第二个field_image_fid, 就是关联file_managed 中的fid的,这三个表,组成了一条完整的node记录

node表:实现记录的基本资料

file_managed表:保存图片存放地址

field_data_field_image表:将node表跟file_managed表通过entiey_id 跟 field_image_fid 关联起来。

赞成!
0
否决!

谢谢诗人,特来奉上第4问(4. 要实现填过详细信息的人,就不需要填第二次了?)写在tpl里的代码 (page--subscribe.tpl.php)以方便更多的人。

    <?php	
   print $user->name; // 打出当前用户名看看
   echo "<br><br><br>";//空几行
  
  $result = db_query('SELECT user_name FROM {subscribe}');
  $re=$result->fetchAll();//官网查的drupal 数据库抽取语句 抽取的是subscribe 里面 user_name 字段里面的所有
 
  foreach($re as $row){//这个循环只为循环输出看一下是不是ok
  print $row->user_name."-----";
  }
   echo "<br><br><br>";//空几行
  foreach($re as $row){// 这里做判断了,如果配对出去match 如果不配对输出no match
  	if($user->name==$row->user_name){
	 echo "match"."<br>";
	}
	else {echo "no match"."<br>";}
  }
?>

页面结果:

Yufei Tin


Ssiufoo Tin-----ssiufoo-----Yufei Tin-----Henry Evans-----

 

no match

no match

match
no match

 

ps:我数据库subscribe表里面只有4条 

 

 

再次思考:是否可以做个关联subscribe 表里面的sid 关联到user 表里面的uid, 然后uid 有插入 subscribe也有相同数值插入到sid,uid 删除sid的那一行也删除,其他字段值置为空。(这个数据库关联是可行的)用户注册,直接就在subscribe 里面多了一个sid字段值和uid相同的。

这样就不用每次全部user_name 抽出来做比较了。 直接用当前用户uid抽subscribe里面对应的sid ,如果user_name 为空,证明,没有提交详情。

这样的话,或许不会出现subscribe表数据多了,foreach抽全部来比较会让系统变慢了。 

但这个用户提交详情要就需要让数据插入到相应的sid 表下。(这个不知道php 怎么写好)

赞成!
0
否决!

再次感谢诗人,相当详细O(∩_∩)O  

ps:头像怎么变得那么丑了,我还是自己上传一个吧 #_#