isset,array_key_exists和!empty的解决方法

时间:2013-12-11 22:38:58

标签: php arrays

编码php时,尽量避免使用尽可能多的警告。关于数组,有一个问题让我困扰了很长一段时间。

在处理数组及其值时,我经常在进入“实际工作”之前检查空值。

if(array_key_exists('bla', $array){
  if( !empty($array['bla']) {
    # do something
  }
}

我的问题是:

这是很多代码,只是检查我是否有值可以使用。是否有一些更短的方法来检查数组中可能存在或不存在的值?

5 个答案:

答案 0 :(得分:5)

请不要使用empty,除非您确定这是您想要的:

  

如果FALSE存在并且具有非空的非零值,则返回var。否则返回TRUE

     

以下内容被认为是空的:

     
      
  • ""(空字符串)
  •   
  • 0(0为整数)
  •   
  • 0.0(0作为浮动)
  •   
  • "0"(0为字符串)
  •   
  • NULL
  •   
  • FALSE
  •   
  • array()(空数组)
  •   
  • $var;(声明的变量,但没有值)
  •   

本手册没有明确列出“if var 不存在”案例,但这里有几个:

  • $array['undeclaredKey'](现有数组,但未声明密钥)
  • $undeclaredVar;(未声明的变量)

通常array_key_exists检查就足够了。

答案 1 :(得分:3)

你可以简单地做

if (!empty($array['bla']) {
 # do something
}

我一直在drupal中使用它,并且是检查是否可用并避免任何类型警告的好方法。

答案 2 :(得分:2)

只是做:

if (!empty($array['bla'])) {

如果密钥不存在,则不会发出警告。

答案 3 :(得分:1)

不确定为什么还没有人提到,但你可以这样做:

// Before
if(array_key_exists('bla', $array){
    if( !empty($array['bla']) {

// After (if element of array is scalar)
//   Avoids warning and allows for values such as 0
if ((true === isset($array['bla'])) && (mb_strlen($array['bla']) > 0)) {

// After (if element of array is another array
//   Avoids warning and ensures element is populated
if ((true === isset($array['bla'])) && (count($array['bla']) > 0)) {

如果你真的想要更好地检查vars,你可以创建一个标准化的API,下面是我创建的一些方法,以避免变量检查的清单函数调用:

class MyString
{
    public static function populated($string)
    {
        //-----
        // Handle various datatypes
        //-----

        // Don't want to assume an array as a string, even if we serialize then check
        if (is_array($string)) {
            return false;
        }

        if (is_object($string)) {

            if (!is_callable(array($string, '__toString'))) {
                return false;
            }

            $string = (string) $string;
        }
        //-----

        return (mb_strlen($string) > 0) ? true : false;
    }
}

class MyArray
{
    public static function populatedKey($key, $array, $specificValue = null, $strict = true)
    {
        if ((is_array($array)) &&
            (array_key_exists($key, $array))) {

            if (is_array($array[$key])) {
                return (count($array[$key]) > 0) ? true : false;
            }

            elseif (is_object($array[$key])) {
                return true;
            }

            elseif (mb_strlen($array[$key]) > 0) {

                if (!is_null($specificValue)) {

                    if ($strict === true) {
                        return ($array[$key] === $specificValue) ? true : false;
                    } else {
                        return ($array[$key] == $specificValue) ? true : false;
                    }
                }

                return true;
            }
        }

        return false;
    }
}

// Now you can simplify calls

if (true === MyArray::populatedKey('bla', $array)) { // Do stuff }

if (true === MyString::populated($someString)) { // Do stuff }

有一种方法可以对猫进行换肤,但是标准化这样的调用会增加快速应用程序开发(RAD),保持调用代码干净,并有助于自我文档(语义逻辑)。

答案 4 :(得分:1)

如果要检查非空值,则可以使用/// <summary> /// This class contains extensions methods for the <see cref="MessageSender"/> class. /// </summary> public static class MessageSenderExtensions { private const string BrokeredMessageListCannotBeNullOrEmpty = "The brokeredMessageEnumerable parameter cannot be null or empty."; private const string SendPartitionedBatchFormat = "[MessageSender.SendPartitionedBatch] Batch Sent: BatchSizeInBytes=[{0}] MessageCount=[{1}]"; private const string SendPartitionedBatchAsyncFormat = "[MessageSender.SendPartitionedBatchAsync] Batch Sent: BatchSizeInBytes=[{0}] MessageCount=[{1}]"; private const int MaxBathSizeInBytes = 262144; /// <summary> /// Sends a set of brokered messages (for batch processing). /// If the batch size is greater than the maximum batch size, /// the method partitions the original batch into multiple batches, /// each smaller in size than the maximum batch size. /// </summary> /// <param name="messageSender">The current <see cref="MessageSender"/> object.</param> /// <param name="messages">The collection of brokered messages to send.</param> /// <param name="trace">true to cause a message to be written; otherwise, false.</param> /// <returns>The asynchronous operation.</returns> public async static Task SendPartitionedBatchAsync(this MessageSender messageSender, IEnumerable<BrokeredMessage> messages, bool trace = false) { var brokeredMessageList = messages as IList<BrokeredMessage> ?? messages.ToList(); if (messages == null || !brokeredMessageList.Any()) { throw new ArgumentNullException(BrokeredMessageListCannotBeNullOrEmpty); } var batchList = new List<BrokeredMessage>(); long batchSize = 0; foreach (var brokeredMessage in brokeredMessageList) { // Hack because the size of the brokered message does not take into account the size of the properties var messageSize = GetObjectSize(brokeredMessage.Properties) + brokeredMessage.Size; if ((batchSize + messageSize) > MaxBathSizeInBytes) { // Send current batch await messageSender.SendBatchAsync(batchList); Trace.WriteLineIf(trace, string.Format(SendPartitionedBatchAsyncFormat, batchSize, batchList.Count)); // Initialize a new batch batchList = new List<BrokeredMessage> { brokeredMessage }; batchSize = messageSize; } else { // Add the BrokeredMessage to the current batch batchList.Add(brokeredMessage); batchSize += messageSize; } } // The final batch is sent outside of the loop await messageSender.SendBatchAsync(batchList); Trace.WriteLineIf(trace, string.Format(SendPartitionedBatchAsyncFormat, batchSize, batchList.Count)); } /// <summary> /// Calculates the lenght in bytes of an object and returns the size. /// </summary> private static int GetObjectSize(object objectToTest) { var bf = new BinaryFormatter(); using (var ms = new MemoryStream()) { bf.Serialize(ms, objectToTest); return ms.ToArray().Length; } } }

您还可以使用!empty($array['bla']),在以下情况下返回isset($array['bla']):1)未定义密钥或2)如果为密钥存储的值为false。检查数组是否包含键(即使其值为null)的唯一简单方法是使用null

即使密钥存在,array_key_exists()的呼叫也是安全的(行为类似于empty()),因此您无需通过isset()保护密码。

我很惊讶没有提到这一点,但是获取密钥值而不产生警告/错误的最短方法是使用Error Control Operator

array_key_exists()

这允许您获取任何键的值,如果该键不存在,则返回值的可能性为// safely fetch from array, will return NULL when key doesn't exist $value = @$array['bla'];