Drupal 8 db query

查询:

$database = \Drupal::database();
$result = $database->query('SELECT * FROM {xx} where ID=:id', [':id' => 1]);


# OBJ查询
$result = $database->select('players', 'p')
->fields('p')
->condition('id', 1)
->execute();

获取结果:

#1
foreach($result as $record) {
  $id = $record->id
}

#2
$records = $result->fetchAll();
$records = $result->fetchAllAssoc('id');

为什么localhost无法连接到Mysql数据库?

在做开发的时候肯定无数人都碰到过这种无法连接数据库的情况, 当你把连接的Host改成127.0.0.1以后又正常了.

先来说说两者的区别:
1. 127.0.0.1 127.0.0.1走的是TCP/IP协议。
2. localhost 使用Localhost走的是socket协议.

那就很简单. 证明问题出在Socket身上.

PHP mysql socket配置
我们可以先打印phpinfo()看看php配置里mysqli.default_socket配置

发现指向了/var/mysql/mysql.sock

Mysql Socket配置
接着再看看mysql的socket地址

发现指向了/tmp/mysql.sock

问题很明显了,是这两个Socket不对应

有三种办法解决问题:
1. 修改php.ini把配置指向 /tmp/mysql.sock(具体还是根据mysql配置来)
2. 连接数据库的时候配置Socket

Mysqli
在使用mysqi函数的时候可以看到最后一个是Socket

new mysqli('localhost', 'root', 'root', '3306', '/tmp/mysql.sock');

Drupal
Drupal 需要增加一项为Unix_socket

最后还是推荐改PHP.ini配置,一劳永逸的事

Drupal 8 services

一个service是一个Service Container(Service容器, 包含所有Service,也可以叫Service的统一管理器)的实例化对象. 用于重复的操作和使用. 就好比面向过程写法中的函数封装. 那为什么不使用普通类而是使用Service呢?

  • 依耐注入
  • 方便管理
  • 支持Tagged

获取Service
$server = \Drupal::services(‘your_service_sname’);

控制器注入Services

namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;

class MymoduleController extends ControllerBase {

  protected $dateFormatter;

  /**
   * 初始化的时候将service: date.formatter注入.
   *
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter service.
   */
  public function __construct(DateFormatterInterface $date_formatter) {
    $this->dateFormatter = $date_formatter;
  }

  /**
   * 这里是初始化__construct的参数. create函数会接收Service Container参数.然后获取你需要的service作为参数.
   *
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('date.formatter')
    );
  }
}

举例为什么使用Service

这边我们有一个需求,可以根据一个类管理器来获取所有类,而且自动调用,不用去new。可以自动传参数. 或者动态获取参数

此处有一个类. 负责打印一个$name

class A {
  public $name;
  public function __construct($name) {
    $this->name = $name;
  }

  public function printName() {
    print $this->name;
  }
}

如果想使用很简单. 我们要打印的是$_SESSION里面的name.

$a = new A($_SESSION['name']);
$a->printName();

现在我们要做一个类管理器. 这个类管理器负责获取和管理所有类

class StaticContainer {
  public static function get($class_name) {
    return new $class_name();
  }
}

StaticContainer::get('A')->printName();

但是这样会报错,所以我们需要一个配置,让传默认参数.

session_start();
$_SESSION['name'] = 'xiukun';


class A {
  public $name;
  public function __construct($name) {
    $this->name = $name;
  }

  public function printName() {
    print $this->name;
  }
}

class B {

}

// 这里就像我们service就的配置
function classConfig() {
  return [
    'A' => [
      'class_name' => 'A',
      'arguments' => [$_SESSION['name']]
    ],
    'B' => [
      'class_name' => 'B'
    ]
  ];
}

class StaticContainer {
  private static $classConfig;
  public static function get($class_name) {
    if(!isset(self::$classConfig)) {
      self::$classConfig = classConfig();
    }

    if (isset(self::$classConfig[$class_name])) {
      $cname = self::$classConfig[$class_name]['class_name'];
      $args = isset(self::$classConfig[$class_name]['arguments']) ?
        self::$classConfig[$class_name]['arguments'] : [];

      return (new ReflectionClass ($cname))->newInstanceArgs($args);
    }
  }
}

StaticContainer::get('A')->printName();

这样不管在哪静态调用都能自动传参数

Drupal 8 field_purge_batch错误

在使用了一段Drupal 8时间以后,一直出现一个错误.

Error: Call to a member function getTargetEntityTypeId() on array in field_purge_batch() (line 82 of /Users/xiukun/www/drupal/core/modules/field/field.purge.inc) #0 /Users/xiukun/www/drupal/core/modules/field/field.module(167): field_purge_batch(50) #1 [internal function]: field_cron() #2 /Users/xiukun/www/drupal/core/lib/Drupal/Core/Extension/ModuleHandler.php(391): call_user_func_array('field_cron', Array) #3 /Users/xiukun/www/drupal/core/lib/Drupal/Core/Cron.php(235): Drupal\Core\Extension\ModuleHandler->invoke('field', 'cron') #4 /Users/xiukun/www/drupal/core/lib/Drupal/Core/Cron.php(133): Drupal\Core\Cron->invokeCronHandlers() #5 /Users/xiukun/www/drupal/core/lib/Drupal/Core/ProxyClass/Cron.php(75): Drupal\Core\Cron->run() #6 /Users/xiukun/www/drupal/core/modules/automated_cron/src/EventSubscriber/AutomatedCron.php(65): Drupal\Core\ProxyClass\Cron->run() #7 /Users/xiukun/www/drupal/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(108): Drupal\automated_cron\EventSubscriber\AutomatedCron->onTerminate(Object(Symfony\Component\HttpKernel\Event\PostResponseEvent), 'kernel.terminat...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #8 /Users/xiukun/www/drupal/vendor/symfony/http-kernel/HttpKernel.php(88): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.terminat...', Object(Symfony\Component\HttpKernel\Event\PostResponseEvent)) #9 /Users/xiukun/www/drupal/vendor/stack/builder/src/Stack/StackedHttpKernel.php(32): Symfony\Component\HttpKernel\HttpKernel->terminate(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Cache\CacheableResponse)) #10 /Users/xiukun/www/drupal/core/lib/Drupal/Core/DrupalKernel.php(635): Stack\StackedHttpKernel->terminate(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Cache\CacheableResponse)) #11 /Users/xiukun/www/drupal/index.php(22): Drupal\Core\DrupalKernel->terminate(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Cache\CacheableResponse)) #12 {main}.

接着我去找到空上函数,打印了一下数据

$deleted_fields_repository = \Drupal::service('entity_field.deleted_fields_repository');
$fields = $deleted_fields_repository->getFieldDefinitions(NULL);
print_r($fields);

发现第一个第二个是数组,数组怎么会有对象呢
但是这里也就是获取一个Type,所以我去修改代码.

foreach ($fields as $field) {
  if(!is_array($field)) {
     $entity_type = $field->getTargetEntityTypeId();
     .....

TO

foreach ($fields as $field) {
  if(!is_array($field)) {
     if(!is_array($field)) {
       $entity_type = $field->getTargetEntityTypeId();
     }else{
       $entity_type = $field['entity_type'];
     }
     .....

接着再Run : field_purge_batch in devel。 Fixed. 这个问题估计是删除字段的时候没有删除干净

Drupal 8 字段

获取字段配置:

$field = FieldStorageConfig::loadByName('node', 'field_module_version')
// 获取所有配置
print_r($field->getSettings());


// 获取字段允许字段
$field->getSetting('allowed_values');

Drupal 8 entityQuery

# 获取所有的Node,返回ID
$ids = \Drupal::entityQuery('node')->execute();
dpm($ids);

# 根据条件进行查询
$EntityQueryGetId = \Drupal::entityQuery('project_list')
->condition('field_short_name', $content['field_module_name'])->execute();

	

Drupal 7制作可滚动的Banner

需要的模块:config_pages(用于配置Banner图片,需要一个多图字段), flexslider, linkimage

function mymodule_block_info() {
  // This example comes from node.module.
  $blocks['banner'] = array(
    'info' => t('Banner'),
    'cache' => DRUPAL_NO_CACHE
  );

  return $blocks;
}

function mymodule_block_view($delta = '') {
  if($delta == 'banner') {

    $config = config_pages_config('banner');
    if ($config) {
      // load flexslider.
      $optionset = flexslider_optionset_load('default');
      flexslider_add('block-invest-banner', $optionset);
    }

    // render item.
    $items = array();
    foreach($config->raw()->field_banner_slider['und'] as $image_item) {
      $items[] = theme('linkimage_formatter', array('item' => $image_item, 'image_style' => 'newbanner'));
    }
    $item_list = theme('item_list', array('items' => $items, 'attributes' => array('class' => array('slides'))));
    return array(
      'content' => '
' . $item_list . '
', ); } }