Нужен совет по оптимизации функции

1.31K
.
# Delphinum (26.08.2016 / 21:56)
ДоХтор, ну это естественно, для того функции и нужны. Проблема только в том, что никто не знает, когда понадобится та или иная функция. Я считаю (перенося опыт из ООП), что у функции должна быть "одн
Я понял, благодарю
.

Delphinum, сделал разделение... На мой взгляд стало ещё хуже -- кода больше, и читабельность снизилась. Да и где-то у меня в логике ошибка, потому что теперь не работают вызовы более одного. Но мне нужен ответ на вопрос, правильно ли я сделал разделение? Что-то мне подсказывает, что нет

Набор функций (+/-)
session_id() ?: session_start();

function getNameFile($id) {
    $dir = 'data';
    is_dir($dir) ?: mkdir($dir);
    $nameFile = $dir .'/'. $id .'.txt';
    
    return $nameFile;
}

function getMaxTime($days = 1) {
//  $maxTime = $time + 3600 * 24 * $days;
    $maxTime = time() + 15; # <---Строка для теста
    
    return $maxTime;
}

function getData($id) {
    $nameFile = getNameFile($id);
    $maxTime = getMaxTime();

    $data = (!file_exists($nameFile) ? ['tm' => $maxTime, 'cnt' => 0]
        : unserialize(file_get_contents($nameFile)));
        
    return $data;
}

function setData($id) {
    $nameFile = getNameFile($id);
    $maxTime = getMaxTime();
    $data = getData($id);
    
    $id = (isset($_GET['id']) ? trim(strip_tags($_GET['id'])) : $id);
    $go = (isset($_GET['go']) ? trim(strip_tags($_GET['go'])) : '');
        
    if (!empty($go)) {
        $data['cnt']++;
        file_put_contents($nameFile, serialize($data));
        header('Location: '. $go);
        exit;
    }
    
    if ($data['tm'] < time()) { // Перезапись
        $data['tm'] = $maxTime;
        $data['cnt'] = 0;
        file_put_contents($nameFile, serialize($data));
    }
}

function outData($id, $href, $name, $clicks = 10) {
    $nameFile = getNameFile($id);
    $maxTime = getMaxTime();
    $data = getData($id);
    setData($id);

    return ($data['tm'] >= time() && $data['cnt'] < $clicks ? '<a href="?id='. $id .
        '&go='. $href .'">'. $name .'</a> ('. ($clicks - $data['cnt']) .')<br/>' : '');
}

function i() {
    static $i = 0;
    return ++$i;
}
Использование (+/-)
echo outData(
    i().session_id(),
    basename(__FILE__),
    'Тест'
);
.
Delphinum

ДоХтор, Я бы подкорректировал семантику функций:
getNameFile -> getFilePath
setData($id) -> setData($id, $data)
outData - не понял что эта функция должна делать

Опиши мне задачу подробнее, я напишу как бы сделал я.

.
Delphinum
outData - не понял что эта функция должна делать
Проверять время и число кликов, и в зависимости от их значений, возвращать ссылку с числом оставшихся кликов, или пустую строку
Опиши мне задачу подробнее
Отобразить ссылку и число допустимых кликов по этой ссылке, а так же - задать отрезок времени, по истечению которого число кликов будет обнуляться.
.

ДоХтор, ну если ты работал через файлы, я так и продолжу:

<?php
// Model
/**
 * Создает ссылку.
 *
 * @param string $href Адрес ссылки.
 * @param string $label Текст ссылки.
 * @param int $clickLimit Число допустимых кликов по ссылке.
 *
 * @return array Структура ссылки.
 */
function createLink($href, $label, $clickLimit = 10){
  return [
    'href' => $href,
    'label' => $label,
    'currentClicks' => 0,
    'clickLimit' => 10,
    'added' => time(),
  ];
}

/**
 * Загружает конфигурацию ссылки из файла.
 *
 * @param string $file Адрес файла, хранящего конфигурацию ссылки.
 *
 * @return array|null Конфигурация ссылки.
 */
function loadLink($file){
  if(!file_exists($file)){
    return null;
  }
  return unserialize(file_get_contents($file));
}

/**
 * Сохраняет конфигурацию ссылки в файл.
 *
 * @param string $file Целевой файл.
 */
function saveLink($file){
  file_put_contents(serialize($file));
}

// View
function renderLink(array $link){
  return '<a href="' . $link['href'] . '">' . $link['label'] . '</a>';
}

// Controller
function route($regex, callable $handler){
  $match = [];
  if(preg_match($regex, $_SERVER['REQUEST_URI'], $match) === false){
    return $handler($match);
  }
  return false;
}
?>


Использование:
<?php
// Заход на главную страницу
route('/', function(array $match){
  // Получаем ссылку или создаем новую
  $link = loadLink('test.link');
  if(is_null($link)){
    $link = createLink('http://site.com?link=test', 'текст', 15);
  }

  echo renderLink($link);
});

// Заход на страницу со ссылкой
route('?link=test', function(array $match){
  $link = loadLink('test.link');
  // Если такой ссылки еще нет, просто создаем новую
  if(is_null($link)){
    $link = createLink('http://site.com?link=test', 'текст', 15);
  }
  // Если ссылка была создана более дня назад, обновляем ее
  elseif(($link['added'] - (new DateTime('+1 day'))->getTimestamp()) < time()){
    $link = createLink('http://site.com?link=test', 'текст', 15);
  }

  // Сохраняем и отображаем ссылку
  $link['currentClicks']++;
  saveLink($link);
  echo renderLink($link);
});
?>


Не знаю, рабочий ли это код, но надеюсь смысл будет понятен.
.
elseif(($link['added'] - (new DateTime('+1 day'))->getTimestamp()) < time()){

тут должен быть не минус, а плюс
.

Delphinum, спасибо за код ) На мой взгляд, такой подход ближе к ооп. А для процедурного, наверное, всё-таки будет ближе мой вариант (с множеством global внутри функции). Я не настаиваю на этом, это моё мнение, и оно может быть ошибочным.

Всего: 47