• Как можно на php файл в кодировке utf8 with bom преобразовать в without bom?

    nazarpc
    @nazarpc
    Open Source enthusiast
    function without_bom ($text) {
        if (substr($text, 0, 3) == "\xEF\xBB\xBF") {
            return substr($text, 3);
        }
        return $text;
    }

    https://en.wikipedia.org/wiki/Byte_order_mark
    Ответ написан
    2 комментария
  • Как в JQuery UI tabs сделать deep linking?

    Deonisius
    @Deonisius
    Родился в 11110110111 году, 11000 января.
    $("#tabs").tabs({
      create: function(e, ui) {
        location.hash = ui.panel.selector;
      },
      activate: function(e, ui) {
        location.hash = ui.newPanel.selector;
      }
    });
    Ответ написан
    5 комментариев
  • По какой причине может удваиваться в JS index элемента?

    petermzg
    @petermzg
    Самый лучший программист
    .index()
    "Ищет указанный элемент в наборе jQuery и возвращает его индекс (порядковый номер в наборе начиная с 0)"
    У вас набор этот состоит из одного элемента $(this), так что self.index() всегда вернет 0.
    Лучше сделать так:
    stepList.each(function(index) {
      $(this).find('.current').append(index+1);
    }
    Ответ написан
    1 комментарий
  • Как получить с JQuery номер текущего элемента?

    @westy
    Вы получаете список объектов $('div.step'). Потом к списку применяете метод $('div.step').index(). Так вот он возвращает номер только первого объекта из списка. Вам надо полученный список обойти в цикле, чтоб узнать позицию каждого.
    Примерно так
    var stepList = $('div.step');// Ищем все элементы, получаем список элементов
    stepList.each(function() {// Проходим по каждому элементу циклом
        var self = $(this);// Получаем текущий элемент в цикле
        var index = self.index();// Узнаем его порядковый номер относительно списка элементов stepList
        self.find('h3').append(index);// В H3 вставляем номер
    });
    Ответ написан
    1 комментарий
  • В чем профит такого способа написания if()?

    petermzg
    @petermzg
    Самый лучший программист
    Страховка от присваивания. Чтобы вы не присвоили переменной значения вместо сравнения с ней.
    Ответ написан
    Комментировать
  • Как сделать pager в Zend Framework 1?

    27cm
    @27cm
    TODO: Написать статус
    В представление теперь нужно передавать объект Zend_Paginator (массив фильмов, разбитый на страницы). Приведу самый простой вариант, используя Zend_Paginator_Adapter_Array. Как только освоитесь с ним, можете переписать через адаптер, использующий БД:
    public function indexAction()
    {
        $movies = new Application_Model_DbTable_Movies();
        $paginator = Zend_Paginator::factory($movies->fetchAll());
        $paginator->setItemCountPerPage(15);
    
        $page = $this->_getParam('page', 1);
        $paginator->setCurrentPageNumber($page);
        
        $this->view->movies = $paginator->getCurrentItems();
        $this->view->paginator = $paginator;
    }


    В шаблон добавить вывод постраничной навигации:
    <table>
        <tr>
            <th>Название</th>
            <th>Режиссёр</th>
            <th> </th>
        </tr>
        <?php echo $this->partialLoop('partials/movie.phtml', $this->movies); ?>
    </table>
    <?php echo $this->paginationControl($this->paginator, 'Sliding', 'pagination_control.phtml'); ?>


    И сам шаблон для постраничной навигации. Примеры есть в документации:
    framework.zend.com/manual/1.12/ru/zend.paginator.u...

    На ZF1 сейчас нет особо смысла учиться писать. Скоро уже ZF3 выйдет.
    Пример разработки блога на Zend Framework 2
    Ответ написан
  • Есть ли утилита под линукс, которая при удалении или форматировании забивает раздел или файл нулями и единицами сначала?

    Olej
    @Olej
    инженер, программист, преподаватель
    $ sudo cat /dev/zero > /dev/sda1
    ;-)
    Не нужны в Linux какие-то особые команды ... если вы хорошо понимаете что вы хотите сделать.
    Ответ написан
    8 комментариев
  • Чей код чище и удобнее расширятся битрикс или модх?

    MetaDone
    @MetaDone
    Хорошо сформулированный вопрос - 50% решения
    что угодно лучше битрикса. И да простят меня бывалые битриксойды, но лично я с таким месивом работать не намерен.
    Просто кусок кода, который битрикс малый бизнес генерирует после установки в index.php
    spoiler
    <?
    require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
    $APPLICATION->SetTitle("Интернет-магазин \"Одежда\"");
    ?>
    <h2>Лучшие коллекции</h2>
    <?$APPLICATION->IncludeComponent("bitrix:catalog.top", "", array(
    		"IBLOCK_TYPE_ID" => "catalog",
    		"IBLOCK_ID" => "2",
    		"ELEMENT_SORT_FIELD" => "name",
    		"ELEMENT_SORT_ORDER" => "asc",
    		"ELEMENT_SORT_FIELD2" => "name",
    		"ELEMENT_SORT_ORDER2" => "asc",
    		"HIDE_NOT_AVAILABLE" => "N",
    		"ELEMENT_COUNT" => "8",
    		"LINE_ELEMENT_COUNT" => "4",
    		"PROPERTY_CODE" => array(0=>"MINIMUM_PRICE",1=>"MAXIMUM_PRICE",2=>"",),
    		"OFFERS_FIELD_CODE" => array(0=>"NAME",1=>"",),
    		"OFFERS_PROPERTY_CODE" => array(0=>"ARTNUMBER",1=>"COLOR_REF",2=>"SIZES_SHOES",3=>"SIZES_CLOTHES",4=>"MORE_PHOTO",5=>"",),
    		"OFFERS_SORT_FIELD" => "sort",
    		"OFFERS_SORT_ORDER" => "asc",
    		"OFFERS_SORT_FIELD2" => "id",
    		"OFFERS_SORT_ORDER2" => "desc",
    		"OFFERS_LIMIT" => "0",
    		"VIEW_MODE" => "SLIDER",
    		"TEMPLATE_THEME" => "site",
    		"PRODUCT_DISPLAY_MODE" => "Y",
    		"ADD_PICT_PROP" => "MORE_PHOTO",
    		"LABEL_PROP" => "NEWPRODUCT",
    		"OFFER_ADD_PICT_PROP" => "MORE_PHOTO",
    		"OFFER_TREE_PROPS" => array(0=>"COLOR_REF",1=>"SIZES_SHOES",2=>"SIZES_CLOTHES",),
    		"SHOW_DISCOUNT_PERCENT" => "Y",
    		"SHOW_OLD_PRICE" => "Y",
    		"ROTATE_TIMER" => "30",
    		"MESS_BTN_BUY" => "Купить",
    		"MESS_BTN_ADD_TO_BASKET" => "В корзину",
    		"MESS_BTN_DETAIL" => "Подробнее",
    		"MESS_NOT_AVAILABLE" => "Нет в наличии",
    		"SECTION_URL" => "",
    		"DETAIL_URL" => "",
    		"BASKET_URL" => "/personal/cart/",
    		"ACTION_VARIABLE" => "action",
    		"PRODUCT_ID_VARIABLE" => "id_slider",
    		"PRODUCT_QUANTITY_VARIABLE" => "quantity",
    		"PRODUCT_PROPS_VARIABLE" => "prop",
    		"SECTION_ID_VARIABLE" => "SECTION_ID",
    		"CACHE_TYPE" => "A",
    		"CACHE_TIME" => "180",
    		"CACHE_GROUPS" => "Y",
    		"DISPLAY_COMPARE" => "N",
    		"PRICE_CODE" => array(0=>"BASE",),
    		"USE_PRICE_COUNT" => "N",
    		"SHOW_PRICE_COUNT" => "1",
    		"PRICE_VAT_INCLUDE" => "Y",
    		"PRODUCT_PROPERTIES" => array(),
    		"USE_PRODUCT_QUANTITY" => "Y",
    		"CONVERT_CURRENCY" => "N",
    		"OFFERS_CART_PROPERTIES" => array(0=>"ARTNUMBER",1=>"COLOR_REF",2=>"SIZES_SHOES",3=>"SIZES_CLOTHES",)
    	),
    	false
    );?>
    <h2>Тренды сезона</h2>
    <?$APPLICATION->IncludeComponent(
    	"bitrix:catalog.top",
    	"",
    	Array(
    		"IBLOCK_TYPE" => "catalog",
    		"IBLOCK_ID" => "2",
    		"VIEW_MODE" => "SECTION",
    		"TEMPLATE_THEME" => "site",
    		"PRODUCT_DISPLAY_MODE" => "Y",
    		"ADD_PICT_PROP" => "MORE_PHOTO",
    		"LABEL_PROP" => "NEWPRODUCT",
    		"OFFER_ADD_PICT_PROP" => "MORE_PHOTO",
    		"OFFER_TREE_PROPS" => array("COLOR_REF", "SIZES_SHOES", "SIZES_CLOTHES"),
    		"SHOW_DISCOUNT_PERCENT" => "Y",
    		"SHOW_OLD_PRICE" => "Y",
    		"MESS_BTN_BUY" => "Купить",
    		"MESS_BTN_ADD_TO_BASKET" => "В корзину",
    		"MESS_BTN_DETAIL" => "Подробнее",
    		"MESS_NOT_AVAILABLE" => "Нет в наличии",
    		"ELEMENT_SORT_FIELD" => "sort",
    		"ELEMENT_SORT_ORDER" => "asc",
    		"ELEMENT_SORT_FIELD2" => "name",
    		"ELEMENT_SORT_ORDER2" => "asc",
    		"SECTION_URL" => "",
    		"DETAIL_URL" => "",
    		"BASKET_URL" => "/personal/cart/",
    		"ACTION_VARIABLE" => "action",
    		"PRODUCT_ID_VARIABLE" => "id_section",
    		"PRODUCT_QUANTITY_VARIABLE" => "quantity",
    		"PRODUCT_PROPS_VARIABLE" => "prop",
    		"SECTION_ID_VARIABLE" => "SECTION_ID",
    		"DISPLAY_COMPARE" => "N",
    		"ELEMENT_COUNT" => "12",
    		"LINE_ELEMENT_COUNT" => "4",
    		"PROPERTY_CODE" => array("MINIMUM_PRICE", "MAXIMUM_PRICE"),
    		"OFFERS_FIELD_CODE" => array("NAME"),
    		"OFFERS_PROPERTY_CODE" => array("ARTNUMBER", "COLOR_REF", "SIZES_SHOES", "SIZES_CLOTHES", "MORE_PHOTO"),
    		"OFFERS_SORT_FIELD" => "sort",
    		"OFFERS_SORT_ORDER" => "asc",
    		"OFFERS_SORT_FIELD2" => "id",
    		"OFFERS_SORT_ORDER2" => "desc",
    		"OFFERS_LIMIT" => "0",
    		"PRICE_CODE" => array("BASE"),
    		"USE_PRICE_COUNT" => "N",
    		"SHOW_PRICE_COUNT" => "1",
    		"PRICE_VAT_INCLUDE" => "Y",
    		"PRODUCT_PROPERTIES" => array(),
    		"USE_PRODUCT_QUANTITY" => "Y",
    		"CACHE_TYPE" => "A",
    		"CACHE_TIME" => "180",
    		"CACHE_GROUPS" => "Y",
    		"HIDE_NOT_AVAILABLE" => "N",
    		"CONVERT_CURRENCY" => "N",
    		"OFFERS_CART_PROPERTIES" => array("ARTNUMBER", "COLOR_REF", "SIZES_SHOES", "SIZES_CLOTHES")
    	)
    );?>
    <?$APPLICATION->IncludeComponent("bitrix:sale.bestsellers", ".default", array(
    		"HIDE_NOT_AVAILABLE" => "N",
    		"SHOW_DISCOUNT_PERCENT" => "Y",
    		"PRODUCT_SUBSCRIPTION" => "Y",
    		"SHOW_NAME" => "Y",
    		"SHOW_IMAGE" => "Y",
    		"MESS_BTN_BUY" => "Купить",
    		"MESS_BTN_DETAIL" => "Подробнее",
    		"MESS_NOT_AVAILABLE" => "Нет в наличии",
    		"MESS_BTN_SUBSCRIBE" => "Подписаться",
    		"PAGE_ELEMENT_COUNT" => "4",
    		"LINE_ELEMENT_COUNT" => "4",
    		"TEMPLATE_THEME" => "site",
    		"DETAIL_URL" => "",
    		"AJAX_MODE" => "N",
    		"AJAX_OPTION_JUMP" => "N",
    		"AJAX_OPTION_STYLE" => "Y",
    		"AJAX_OPTION_HISTORY" => "N",
    		"CACHE_TYPE" => "A",
    		"CACHE_TIME" => "86400",
    		"BY" => "AMOUNT",
    		"PERIOD" => "30",
    		"FILTER" => array(
    			0 => "CANCELED",
    			1 => "ALLOW_DELIVERY",
    			2 => "PAYED",
    			3 => "DEDUCTED",
    			4 => "N",
    			5 => "P",
    			6 => "F",
    		),
    		"DISPLAY_COMPARE" => "N",
    		"SHOW_OLD_PRICE" => "N",
    		"PRICE_CODE" => array(
    			0 => "BASE",
    		),
    		"SHOW_PRICE_COUNT" => "1",
    		"PRICE_VAT_INCLUDE" => "Y",
    		"CONVERT_CURRENCY" => "N",
    		"BASKET_URL" => "/personal/cart/",
    		"ACTION_VARIABLE" => "action",
    		"PRODUCT_ID_VARIABLE" => "id",
    		"PRODUCT_QUANTITY_VARIABLE" => "quantity",
    		"ADD_PROPERTIES_TO_BASKET" => "Y",
    		"PRODUCT_PROPS_VARIABLE" => "prop",
    		"PARTIAL_PRODUCT_PROPERTIES" => "N",
    		"USE_PRODUCT_QUANTITY" => "N",
    		"SHOW_PRODUCTS_2" => "Y",
    		"CART_PROPERTIES_2" => array(
    			0 => "BRAND_REF",
    			1 => "NEWPRODUCT",
    			2 => "SALELEADER",
    			3 => "",
    		),
    		"ADDITIONAL_PICT_PROP_2" => "MORE_PHOTO",
    		"LABEL_PROP_2" => "SALELEADER",
    		"CART_PROPERTIES_3" => array(
    			0 => "COLOR_REF",
    			1 => "SIZES_SHOES",
    			2 => "SIZES_CLOTHES",
    			3 => "",
    		),
    		"ADDITIONAL_PICT_PROP_3" => "MORE_PHOTO",
    		"OFFER_TREE_PROPS_3" => array(
    			0 => "COLOR_REF",
    			1 => "SIZES_SHOES",
    			2 => "SIZES_CLOTHES",
    		),
    		"AJAX_OPTION_ADDITIONAL" => ""
    	)
    );?>
    <?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>


    Еще вся эта ересь безбожно терзает БД.
    А если глянуть ядро - то там несмотря на всякие придуманные штуки типа пространств имен, трейтов и т.п. до сих пор глобальные переменные и куча констант. Есть классы, методы в которых непонятно зачем оборачивают суперглобальные массивы. В общем смотрите сами, это чисто мое мнение и я не собираюсь работать с битриксом, чего и вам желаю
    Ответ написан
    4 комментария
  • Вопросы по быстродействию + Какую базу лучше всего использовать?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    все зависит от того что вы с этими данными делать будете. Если просто хранить - то выдержит конечно. Если делать сложные выборки - то зависит от нагрузки и количества запросов а так же расставили вы индексы или нет ну и все такое. Ну и для такой выборки памяти под индексы надо прилично и тюнить настройки mysql.

    Если вас интересует как ускорить запись - можно сначала загонять все в буфер (redis например) и потом пачками заносить все в базу.

    Если интересует как ускорить чтение - кеширование, индексы, агрегация штуками типа elasticsearch. Но опять же только если у вас есть проблемы с производительностью. Не занимайтесь преждевременной оптимизацией. Сначала напишите нагрузочные тесты и посмотрите насколько все плохо и надо ли что-то делать.
    Ответ написан
    1 комментарий
  • Зачем нужны CMS если есть phpmyadmin?

    sabramovskikh
    @sabramovskikh
    Столько ответивших и никто не пожаловался на вопрос) вопрос самый бредовый.
    Зачем нам самолеты, поезда, автомобили, ведь есть же ноги и ботинки
    Ответ написан
    1 комментарий
  • Как правильно хранить в базе данные о авторизации юзера через социальную сеть?

    Serhioromano
    @Serhioromano
    Web Developer
    Не первое и не втрое. Создавать отдельную табилцу на каждую соц сеть не резонно. Нужно создать одун таблицу справочник как поивел пример unity_ultra_hardcore: для всех социальных сетей. Просто в ней нужно специальное поле идентификатор соц. сети.
    Ответ написан
    1 комментарий
  • Как правильно хранить в базе данные о авторизации юзера через социальную сеть?

    @unity_ultra_hardcore
    У нас используется следующая схема таблиц:
    Table "public.social_account"
       Column    |              Type              | Modifiers
    -------------+--------------------------------+-----------
     user_id     | integer                        | not null
     network     | character varying(255)         | not null
     external_id | character varying(255)         | not null
     created_at  | timestamp(0) without time zone | not null
     updated_at  | timestamp(0) without time zone | not null
     id          | uuid                           | not null
    Indexes:
        "social_account_pkey" PRIMARY KEY, btree (id)
        "unique_social_account" UNIQUE, btree (network, external_id)
        "idx_f24d8339a76ed395" btree (user_id)
    Foreign-key constraints:
        "fk_f24d8339a76ed395" FOREIGN KEY (user_id) REFERENCES app_user(id) ON DELETE CASCADE


    То есть для каждой привязки хранится запись, в которой содержится user_id, название соцсети (google/vk/facebook/etc) и id этой соцсети (у всех произвольный формат).
    Таким образом, когда пользователь аутентифицируется через одну из этих соцсетей, сначала ищется user_id по связке external_id + network. Если user_id найден - аутентифицируем текущего пользователя как этот user_id. Если нет, получаем от соцсети email и по нему ищем пользователя в таблице пользователей. Если нашли, то создаем запись в social_account и аутентифицируем юзера. Если не нашлось ничего (первый визит), то создаем пользователя и создаем запись в social_account.
    Ответ написан
  • Как загрузить картинки с ЧПУ?

    Defman21
    @Defman21
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteRule ^(.*)$ index.php?q=$1 [QSA,L]
    Ответ написан
    9 комментариев
  • Как сравнить два массива по первому символу значений и при совпадении удалить эти значения из первого массива?

    @magazovski
    <?php
    
    $a = array(
        "0-1439802876-55d1a5fc8879e.jpg",
        "1-1439802876-55d1a5fc8ed30.jpg",
        "2-1439802876-55d1a5fc95a91.jpg",
    );
    
    $b = array(
        "0-1440719577-55dfa2d9195ec.jpg",
        "2-1440719577-55dfa2d93572b.jpg",
        "3-1440719577-55dfa2d951c51.jpg",
    );
    
    $a = array_combine(array_map(function ($v) {
        return substr($v, 0, strpos($v, '-'));
    }, $a), $a);
    
    $b = array_combine(array_map(function ($v) {
        return substr($v, 0, strpos($v, '-'));
    }, $b), $b);
    
    print_r($a+$b);
    Ответ написан
    3 комментария
  • Как получить GET параметры в MVC?

    copist
    @copist
    Empower people to give
    Позвольте всобачить сюда свой велосипед. Так сказать, самый сок.

    Пример разбора параметров $_GET:
    <?php
    class AppRequest {
    
    	protected $_get;
    
    	/**
    	 * Normalizes the request data
    	 * This method strips off slashes in request data if get_magic_quotes_gpc() returns true
    	 */
    	protected function normalizeRequest() {
    		if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
    			if(isset($_GET)) {
    				$_GET = $this->stripSlashes($_GET);
    			}
    		}
    		if(isset($_GET)) {
    			$this->_get = $_GET;
    		}
    	}
    
    	/**
    	 * Returns the named GET parameter value
    	 * If the GET parameter does not exist, the second parameter to this method will be returned
    	 * @param string $name the GET parameter name
    	 * @param mixed|null $default the default parameter value if the GET parameter does not exist
    	 * @return mixed|null the GET parameter value
    	 */
    	public function getQueryVar($name, $default = null) {
    		if (isset($this->_get[$name])) {
    			return $this->_get[$name];
    		}
    		return $default;
    	}
    
    	/**
    	 * Returns the request URI portion for the currently requested URL
    	 * @return string the request URI portion for the currently requested URL
    	 */
    	public function getRequestUri() {
    		static $requestUri;
    		if (!isset($requestUri)) {
    			if(isset($_SERVER['REQUEST_URI'])) {
    				$requestUri = $_SERVER['REQUEST_URI'];
    				if(!empty($_SERVER['HTTP_HOST'])) {
    					if(strpos($requestUri, $_SERVER['HTTP_HOST']) !== false) {
    						$requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $requestUri);  // remove schema and host name "schema://host/"
    					}
    				} else {
    					$requestUri = preg_replace('/^(http|https):\/\/[^\/]+/i', '', $requestUri); // remove schema and host name "schema://host/"
    				}
    			}
    		}
    		return $requestUri;
    	}
    }

    весь код класса AppRequest

    Вариант логики разбора строки URL:
    Если есть какая-нибудь логика для коротких человеко-читаемых URL, то надо привести их к формату
    controller/action + все дополнительные параметры из URL перенести в переменные $_GET или завести для них отдельный специальный массив в класса AppRequest. Такое можно сделать путём статического разбора строки или регулярными выражениями.

    Пример:
    на вход / -> на выход home/index
    на вход /my-home-page/ -> на выход home/welcome
    на вход /photo/summer.jpg -> на выход gallery/view + $_GET['image-alias'] = 'summer.jpg'
    на вход /wiki/path/to/article.html -> на выход wiki/view + $_GET['page-alias'] = 'path/to/article'

    После этого преобразовать имя контроллера в имя класса, а имя действия - в метод (как в моём велосипеде).
    class HomeController {
        function indexAction() {
            echo "Welcome!";
        }
    }

    Полный пример разбора в классе AppRouter + файл конфигурации с правилами
    Пример правил для указанных выше 4х случаев:
    // Incoming URL mathing rules
    $rules = array(
    	// if request URI is empty
    	'' => array('home', 'index'), // -> код контролера + код действия
    
    	// if request URI looks like /my-home-page/ 
    	'/^my-home-page$/' => array('HomeController', 'indexAction'), // -> имя класса контроллера + имя функции
    
    	// if request URI looks like /photo/summer.jpg
    	'/^/photo/(?<alias>.+)$/' => array('gallery', 'view', array('image-alias' => ':alias')),
    
    	// if request URI looks like /wiki/path/to/article.html
    	'^/wiki/(?<alias>.+)\.html$' => array('wiki', 'view', array('page-alias' => ':alias')),
    );


    А можно поменять роутинг так, чтобы под каждое действие был отдельный класс
    class HomeIndex {
        function run() {
            return new AppResponse("Welcome!");
        }
    }

    В некоторых микро-фреймворках можно даже функции назначать
    function home_index() {
        return new AppResponse("Welcome!");
    }
    $routes = array(
        '/my-home-page/' => 'home_index',
    );

    И даже использовать анонимные функции, тогда у них вся логика приложения вообще в один конфигурационный файл вмещается
    $routes = array(
        '/my-home-page/' => function() { return new AppResponse("Welcome!"); },
    );
    Ответ написан
    Комментировать
  • Как рассчитать уровень относительно опыта?

    bobrovskyserg
    @bobrovskyserg
    Однозначное соответствие между опытом и лв удобно задать функцией.

    зы. пожалуйста, замени слово "розчитать" на что-то менее странное.
    Ответ написан
    3 комментария
  • Как проверить существует ли запись в CSV файле?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    $res = array_udiff($array1, $array2, function($a, $b) {
        if ($a[0] < $b[0]) return -1;
        if ($a[0] > $b[0]) return 1;
        if ($a[1] < $b[1]) return -1;
        if ($a[1] > $b[1]) return 1;
        return 0;
    });

    Но IMHO, лучше для такой цели использовать базу данных.
    Ответ написан
    7 комментариев
  • Не понимаю как получился масив?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    array_rand возвращает ключи массива, а не элементы, поэтому у вас и получается от 0 до 15.
    Если вы делаете shuffle, то вполне достаточно только его:
    $array = range(1, 16);
    shuffle($array);
    echo implode('<br/>', array_slice($array, 0, 4));
    Ответ написан
    Комментировать