Быстрое программирование на php

Ilia

Новичок
Народ подскажите как разрешить глупый вопрос с получением возвращаемых значений функции.

PHP:
<?php $source = Namer($data, "p_title", array('genre_id' => 0), ''); ?>
- стандартный вызов, не устраивает тем что функция будет вызываться много раз с разными параметрами. Возвращает она хэш и в зависимости от места вызова, мне надо доставать из нее тот или иной параметр. Такая система есть в Perl, там все это выглядит так -
PHP:
Namer($data, "p_title", array('genre_id' => 0), '')['url'];
 

Baton

Новичок
Так можно только начиная с php 5.4

Пример взят отсюда: ссылка

PHP:
function foo() {
  return array(1, 2, 3);
}

echo foo()[0]; // 1

Наверняка Ваша версия младше 5.4, иначе бы у Вас получилось. Тогда можно написать обвертку:

PHP:
function get($name, $data){ return $data[$name]; }

get( 'url', Namer($data, "p_title", array('genre_id' => 0), '') );
 
  • Like
Реакции: Ilia

Вурдалак

Продвинутый новичок
Функции неспроста именуют глаголами, потому что функции что-то делают и это должно быть ясно из названия. Если назвать функцию «Дом», то какого хрена она делает? Вот какого хрена делает Namer? Неужели сложно добавить getUrl()?
 

Baton

Новичок
А еще можно вот так, но не советую)))

PHP:
 current(array_slice($r = Namer($data, "p_title", array('genre_id' => 0), ''), array_search('url', array_keys($r) ), 1));
 

С.

Продвинутый новичок
Извратиться можно множеством способов. Но программировать надо не столько быстро, сколько понятно. В вашем случае вызов должен быть примерно таким:
PHP:
<?php $source = Namer($data, "p_title", array('genre_id' => 0), '', 'url'); ?>
Это и быстро, и понятно, и совместимо.
 
  • Like
Реакции: Ilia

Ilia

Новичок
Так можно только начиная с php 5.4

Пример взят отсюда: ссылка

PHP:
function foo() {
  return array(1, 2, 3);
}

echo foo()[0]; // 1

Наверняка Ваша версия младше 5.4, иначе бы у Вас получилось. Тогда можно написать обвертку:

PHP:
function get($name, $data){ return $data[$name]; }

get( 'url', Namer($data, "p_title", array('genre_id' => 0), '') );
Спасибо, да у меня ниже версия - PHP Version 5.3.10-1ubuntu3.2
 

Ilia

Новичок
Извратиться можно множеством способов. Но программировать надо не столько быстро, сколько понятно. В вашем случае вызов должен быть примерно таким:
PHP:
<?php $source = Namer($data, "p_title", array('genre_id' => 0), '', 'url'); ?>
Это и быстро, и понятно, и совместимо.
Спасибо, то что надо!
 

Ilia

Новичок
Функции неспроста именуют глаголами, потому что функции что-то делают и это должно быть ясно из названия. Если назвать функцию «Дом», то какого хрена она делает? Вот какого хрена делает Namer? Неужели сложно добавить getUrl()?
Да да, Спасибо! за вклад в развитие темы!

Отличный форум тут у вас, мне нравится, а вам ?
 

Вурдалак

Продвинутый новичок
Внимание, вопрос: кому из здесь присутствующих понятно что делает
PHP:
$source = Namer($data, "p_title", array('genre_id' => 0), '', 'url');
? IMHO, надо добавть ещё пару тройку аргументов, чтобы стало яснее.
 

Ilia

Новичок
передает пятый аргумент, и не работает естественно!
 

С.

Продвинутый новичок
Вурдалак, совершенно не принципиально в данном контексте. Да, понятнее в сравнении с очень сомнительным Namer(...)[...] или уродом с current(...).
 

Baton

Новичок
и привыкать к говнокоду.

Можно просто возвращать объект, а не массив.
Это где говнокод? Что-то не позволяло топик стартеру сохранить результат в переменную и оттуда брать значение. Я воспринял вопрос буквально, одним выражением получать значение из массива. Если надо именно одним выражением, то пишите обвертку или обновляйтесь до 5.4.
 

Baton

Новичок
А понятно о чем, Вы. Ну если есть возможность править function Names, то можно завести отдельный аргумент под это дело.
 

Ilia

Новичок
Внимание, вопрос: кому из здесь присутствующих понятно что делает
PHP:
$source = Namer($data, "p_title", array('genre_id' => 0), '', 'url');
? IMHO, надо добавть ещё пару тройку аргументов, чтобы стало яснее.
А понятно о чем, Вы. Ну если есть возможность править function Names, то можно завести отдельный аргумент под это дело.
Вы хотите сказать что можно сделать так чтобы 'url' распознавался не как 5ый параметр, а как возвращаемое значение ?
 

Baton

Новичок
Ilia

Если я правильно понимаю всех участников беседы..

Если Вы можете внести изменения в функцию Names и Вам за это не оторвут яйца, то вперед:

PHP:
function Names( $a1, $a2, $a3, $a4, $a5 = null ){
   ...
   $result = array(...);
   //если есть 5й аргумент, то возвращаем элемент из массива $res с ключем $a5, иначе весь массив
   return $a5 !== null ? $result[ $a5 ] : $result;
}
Если у Вас нет возможности вносить изменения в Names и надо во, чтобы то не стало обойтись одним выраженим, то сделайте обвертку и не слушайте никого про говнокод. Никакой это не гавнокод. Просто назовите функцию как нибудь, getItemFromAssoc, и напишите комментарий, для чего потребовалось её создание.
 
  • Like
Реакции: Ilia

Ilia

Новичок
Ilia

Если я правильно понимаю всех участников беседы..

Если Вы можете внести изменения в функцию Names и Вам за это не оторвут яйца, то вперед:

PHP:
function Names( $a1, $a2, $a3, $a4, $a5 = null ){
   ...
   $result = array(...);
   //если есть 5й аргумент, то возвращаем элемент из массива $res с ключем $a5, иначе весь массив
   return $a5 !== null ? $result[ $a5 ] : $result;
}
Если у Вас нет возможности вносить изменения в Names и надо во, чтобы то не стало обойтись одним выраженим, то сделайте обвертку и не слушайте никого про говнокод. Никакой это не гавнокод. Просто назовите функцию как нибудь, getItemFromAssoc, и напишите комментарий, для чего потребовалось её создание.
Отлично, спасибо вам!
 

Духовность™

Продвинутый новичок
Ilia
PHP:
function Names( $a1, $a2, $a3, $a4, $a5 = null ){
   ...
   $result = array(...);
   //если есть 5й аргумент, то возвращаем элемент из массива $res с ключем $a5, иначе весь массив
   return $a5 !== null ? $result[ $a5 ] : $result;
}
А потом добавиться 6, 7, 2034 элемент и будет замечательный говнокод!

Я не понимаю, почему нельзя возвратить stdClass (или иной объект), а нужно писать ущербные пятые параметры?

PHP:
function Namer() 
{
	return (object) array('mykey' => 'val1', 2 => 'val2');
}

echo Namer()->mykey; // val1
 
  • Like
Реакции: Ilia

Духовность™

Продвинутый новичок
Ну и до кучи:

PHP:
<?php
/**
 * Обёртка массива, хранилище.
 * Попытка реализации объекта для более удобной работы с массиво-образной структурой данных
 * в рамках OO-ориентированных PHP-приложений.
 */
class Cover_Array implements IteratorAggregate, Countable, ArrayAccess, Serializable
{
    public function __construct(array $data=array())
    {
        foreach ($data as $key => $value)
        {
            $this->data[$key] = is_array($value) ? new $this($value) : $value;
        }
    }
        protected $data = array();

    public function __get($key)
    {
        return isset($this->data[$key]) ? $this->data[$key] : null;
    }

    public function __set($key, $value)
    {
        $this->data[$key] = is_array($value) ? new $this($value) : $value;
    }

    public function __isset($key)
    {
        return isset($this->data[$key]);
    }

    public function __unset($key)
    {
        unset($this->data[$key]);
    }

    public function getData()
    {
        return $this->data;
    }

    public function setData($data)
    {
        foreach ($data as $key => $value)
        {
            $this->$key = $value;
        }

        return $this;
    }

    public function clear()
    {
        $this->data = array();

        return $this;
    }

    public function __toString()
    {
        return '';
    }

    /**
     * Реализация интерфейса Countable
     *
     * @param void
     * @return int
     */
    public function count()
    {
        return count($this->data);
    }

    /**
     * Реализация интерфейса IteratorAggregate
     *
     * @param void
     * @return ArrayIterator
     */
    public function getIterator()
    {
        return new ArrayIterator($this->data);
    }

    /**
     * Возвращает элемент коллекции с заданным индексом в качестве результата.
     * Аналог parent::__get, но предназначен для числовых индексов.
     *
     * @param mixed
     * @return mixed
     */
    public function item($key)
    {
        return isset($this->data[$key]) ? $this->data[$key] : null;
    }

    /**
     * Присоединяет один элемент в начало массива.
     *
     * @param mixed
     * @return object
     */
    public function prepend($value)
    {
        array_unshift($this->data, self::array2cover($value));

        return $this;
    }

    /**
     * Присоединяет один элемент в конец массива.
     *
     * @param mixed
     * @return object
     */
    public function append($value)
    {
        array_push($this->data, self::array2cover($value));

        return $this;
    }

    /**
     * Возвращает последний элемент массива.
     *
     * @param void
     * @return mixed
     */
    public function getLast()
    {
        $last = end($this->data);
        reset($this->data);
        return $last;
    }

    /**
     * Возвращает первый элемент массива.
     *
     * @param void
     * @return mixed
     */
    public function getFirst()
    {
        $last = end($this->data);
        reset($this->data);
        return $last;
    }

    /**
     * Возвращает данные объекта как массив.
     *
     * @param void
     * @return array
     */
    public function getDataAsArray()
    {
        return self::object2array($this->data);
    }

    /**
     * Реализация метода интерфейса ArrayAccess.
     *
     * @param int|string|null $key ключ элемента
     * @param mixed $value значение элемента
     * @return Cover_Array
     */
    public function offsetSet($key, $value)
    {
        // Это присвоение нового элемента массиву типа $var[] = 'element';
        if ($key === null)
        {
            $u = &$this->data[];
        }
        else
        {
            $u = &$this->data[$key];
        }

        $u = self::array2cover($value);
    }

    /**
     * Реализация метода интерфейса ArrayAccess.
     *
     * @param int|string ключ элемента
     * @return boolean
     */
    public function offsetExists($key)
    {
        return isset($this->data[$key]);
    }

    /**
     * Реализация метода интерфейса ArrayAccess.
     *
     * @param int|string ключ элемента
     * @return void
     */
    public function offsetUnset($key)
    {
        if (isset($this->data[$key]))
        {
            unset($this->data[$key]);
        }
    }

    /**
     * Реализация метода интерфейса ArrayAccess.
     * Отличается от поведения ArrayObject тем, что в случае отсутствия
     * запрошеного элемента не генерирует ошибку, а создает в вызвавшем
     * его объекте, в хранилище, свойство $key содержащее пустой объект
     * Krugozor_Cover_Array.
     *
     * @param int|string ключ элемента
     * @return mixed
     */
    public function offsetGet($key)
    {
        if (isset($this->data[$key]))
        {
            return $this->data[$key];
        }
        else
        {
            return $this->data[$key] = new Krugozor_Cover_Array();
        }
    }

    /**
     * Реализация метода интерфейса Serializable.
     *
     * @return array
     */
    public function serialize()
    {
        return serialize($this->data);
    }

    /**
     * Реализация метода интерфейса Serializable.
     *
     * @param array $data
     * @return Krugozor_Cover_Abstract_Array
     */
    public function unserialize($data)
    {
        $this->setData(unserialize($data));

        return $this;
    }

    /**
     * Преобразует все значения массива $in в массивы, если значения
     * каких-либо элементов данных будут объекты типа Krugozor_Cover_Array.
     *
     * @param array
     * @return array
     */
    protected static function object2array(array $in)
    {
        foreach ($in as $key => $value)
        {
            $in[$key] = (is_object($value) && $value instanceof self)
                        ? $in[$key] = self::object2array($value->getData())
                        : $value;
        }

        return $in;
    }

    /**
     * Возвращает объект Krugozor_Cover_Array, если переданным
     * в метод значением является массив.
     *
     * @param mixed
     * @return mixed
     */
    protected static function array2cover($value)
    {
        return is_array($value) ? new Krugozor_Cover_Array($value) : $value;
    }
}


function Namer() 
{
	return new Cover_Array(array('mykey' => 'val1', 2 => 'val2'));
}

echo Namer()->mykey; // val1
$data = Namer();

echo $data['mykey']; // val1
echo $data[2]; // val2

?>
 

Baton

Новичок
Духовность™

Класс с 4я интерфейсами, для получения итема из массива. Мощно!

Наверное если бы уровень чел-ка в php был достаточным для понимания приведенных Вами классов, то он бы вообще не завел этот топик на форуме.

Там может быть пхп кода всего 100 строчек, а вы ему еще 50 :)
 
Сверху