• Как оптимизировать запрос?

    Не проверял, но что-то типа такого можно сделать:
    SELECT
    	SUM( CASE WHEN `type` = 1 THEN `summ` END) 'dohod', 
    	SUM( CASE WHEN `type` = 2 THEN `summ` END) 'rashod',
    	MONTH(dtr) 'month'
    FROM myevents.event
    WHERE 
      YEAR(dtr) = 2018
      AND `month` BETWEEN 4 AND 5
    GROUP BY `month`


    Читать документацию MySQL:
    Ответ написан
    7 комментариев
  • Фреймворк, макро-Фреймворк для разработки портала?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Не надо писать самому «авторизацию и прочие вещи». Для этого и есть фреймворки и модули.

    Порекомендую Laravel. Он не сложный и очень продуманный, «правильный».
    Ответ написан
    Комментировать
  • Откуда столько посетителей у нового паблика ВК?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Варианты:
    • серые сервисы накрутки;
    • реклама;
    • крупное оффлайн мероприятие;
    • конкурс;
    Ответ написан
    Комментировать
  • Не отправляет сообщение пользователю через апи?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Вы вместо сообщения отправляете массаж : )

    {"key":"massage","value":"11111"}
    Ответ написан
    1 комментарий
  • Можно ли занести несколько значений в переменную в данном php-скрипте?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    wall.post() публикует единственную запись.

    Для промышленных масштабов спама ускорения есть вариант с методом execute(), в который можно обернуть до 25 вызовов АПИ ВКонтакте.

    Т.е. вы на сервере собираете в строку некий код, похожий на JavaScript, что-то типа:
    var params = {
      "message": "Текст поста",
      "from_group": 0,
    };
    var out = { "result": [] };
    
    params.owner_id = 10101; // первая группа
    params.guid = 'abrakadabra';
    out.result.push( API.wall.post(data));
    
    params.owner_id = 20202; // вторая группа
    params.guid = 'drugayaabrakadabra';
    out.result.push( API.wall.post(data));
    // ...
    params.owner_id = 2500025; // 25-я группа
    params.guid = 'uniqueabrakadabra';
    out.result.push( API.wall.post(data));
    
    return out;


    И этот код как текст отправляете параметром code в методе execute()
    Ответ написан
    2 комментария
  • Нужно ли как-то обрабатывать данные из GET запросов?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Надо ли что-то делать с входными данными зависит от того, что с ними дальше делаете.

    Вставляете прямо в сборку строки SQL-запроса? (НЕ надо так делать!)
    Показываете пользователю в теле страницы? (Надо фильтровать)

    Есть готовые функции для валидации и фильтрации входных данных:

    filter_input()

    Например:
    $query = filter_input(
      INPUT_GET,
      'q',
      FILTER_SANITIZE_STRING,
      FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_BACKTICK
    );


    См. подробнее Очищающие фильтры.
    Ответ написан
    Комментировать
  • Почему не пингуются многие сайты гугл?

    Проверьте непингуемые ip в реестре РосКомПозораНадзора: eais.rkn.gov.ru

    (Кому в голову пришло использовать домен ГОВ.ru в русскоязычном интернете, с прямой ассоциацией, несколько принижающей достоинство размещаемых там ведомств : )
    Ответ написан
  • VK API пустые ответы wall.search & newsfeed.search, варианты?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Может, в суточные лимиты упираетесь? Через wall.get() брать записи пробовали? Раз известны группы, лучше .get'ом, наверное.
    Ответ написан
  • Как правильно посчитать количество одинаковых значений в массиве сохранить их число, и удалить их?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Я бы сделал с промежуточным массивом, где ключи – встреченные значения user:
    function mergeCount($arr) {
    
    	$keys = [];
    	foreach($arr as $item) {
    		$id = $item['id'];
    		$user = $item['user'];
    
    		if( isset( $keys[ $user])) {
    			$keys[ $user]['count']++;
    		} else {
    			$keys[$user] = [
    				'id' => $id,
    				'count' => 1
    			];
    		}
    	}
    	
    	$result = [];
    	foreach($keys as $user=>$item) {
    		$result[] = [
    			'id' => $item['count'] > 1 ? $item['count'] : $item['id'],
    			'user' => $user
    		];
    	}
    	
    	return $result;
    }

    Тест
    $data = [
    	['id'=>367, 'user'=>'text'],
    	['id'=>370, 'user'=>'text'],
    	['id'=>432, 'user'=>'text1'],
    	['id'=>234, 'user'=>'text33'],
    	['id'=>264, 'user'=>'text33'],
    ];	
    $a = mergeCount($data);
    print_r($a);
    Результат теста
    Array
    (
        [0] => Array
            (
                [id] => 2
                [user] => text
            )
    
        [1] => Array
            (
                [id] => 432
                [user] => text1
            )
    
        [2] => Array
            (
                [id] => 2
                [user] => text33
            )
    )
    Ответ написан
    1 комментарий
  • Как передать бинарные данные с сервера и на сервер на js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Комментировать
  • Как сделать машину состояний Telegram bot, для поочередного приема ответов на несколько вопросов?

    Недавно делал Telegram бота на Google Spreadsheet и Google Apps Script. Там можно хранить данные ключ-значение.

    Когда приходит сообщение, известен id пользователя, который его написал. На основе этого id делается префикс для ключей, например, "TG_12345" где 12345 id пользователя.

    Возможные диалоги описаны в словаре типа
    { "новый пользователь": [ // название диалога
      {"propmt": "Введите ваше имя"}, // первый вопрос
      {"propmt": "Введите email"},  // второй
      {"propmt": "ник в телеграме"}, // третий
    ], 
      "ещё какой-то диалог":[/* вопросы */]
    }

    И хранить надо состояние диалога для текущего пользователя: название, номер шага и заполненные ранее ответы. Итого ключи могут быть такие:
    TG_12345_DIALOG: "новый пользователь" // из словаря диалогов
    TG_12345_STEP: 2 // текущий шаг, ожидаемый ответ
    TG_12345_REPLY_0: "Иван Петров" // полученные ответы
    TG_12345_REPLY_1: "ivan@mail.ru"
    Ответ написан
    Комментировать
  • Как получить предыдущую дату с moment.js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    moment не пользуюсь, поэтому на чистом JS можно создать дату на сейчас, установить ей нужные день и месяц (1 августа).
    Если дата получилась больше, чем сейчас, надо отнять 1 год:
    var D = new Date();
    D.setDate(1);
    D.setMonth(7);   // 0: Янв, 1: Фев, ... 7: Август
      D.setHours(12);  // опционально
      D.setMinutes(0); // опционально
      D.setSeconds(0); // опционально
    if(D.getTime() > new Date().getTime()) D.setFullYear( D.getFullYear() - 1);
    
    D.toString() // Tue Aug 01 2017 12:00:00 GMT+0300 (MSK)
    
    // и можно из Даты создать объект moment:
    var m = moment(D);


    Наверняка, точно такой же фокус можно провести и с объектом самого moment.
    Ответ написан
    Комментировать
  • Как обрезать число до первой цифры после запятой больше 0?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    1. Рассматривать число как строку.
    2. Найти позицию первого не-ноля после десятичной точки.
    3. Взять строку до неё, включительно.
    p.s. решать вступительные / с собеседования / конкурсные задачи самостоятельно.

    Upd. Если точно на вход будут только числа (0..1), можно так:
    substr($n,0,3 + ceil(-log10(abs($n))) - abs(floor($n)) - 1)
    Ответ написан
    1 комментарий
  • VK API: php-скрипт возвращает ошибку. В чем проблема?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    "message" надо с маленькой буквы.

    У вас сейчас "Message" => $text,
    Ответ написан
    Комментировать
  • Как создать виджет сообщества VK?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Простой способ
    Есть готовое бесплатное приложение для Сообществ "LiveWidget" – там от вас требуется только код самого виджета составить. В вашем сообществе меню три точки - Управление сообществом - Приложения, листаете список предлагаемых приложений до LiveWidget, жмёте «Добавить»:
    скрин
    5af95de14a7d2991085711.png
    Джедайский способ
    В документации по созданию виджета для сообщества всё подробно описано. Вкратце:
    1. создать приложение – Встраиваемое приложение – Приложение сообщества
    2. адресом iframe укажите ваш сервер и папку, где лежит, например, такой HTML
    3. зайдите в ваше Сообщество – меню Управление сообществом – Приложения – выберите там ваше свежесозданное приложение
    4. дайте ему разрешение на добавление виджетов
    5. вставьте код вашего виджета и сделайте его предпросмотр – если в коде виджета нет ошибок, во всплывающем окошке покажут, как он выглядит и предложат установить его в сообщество.
    Скрин приложения
    5af9668c9208d318099967.png
    Код приложения
    <!DOCTYPE html>
    
    <html lang="">
    <head>
        <meta charset="utf-8">
    
        <title>Widgeteer</title>
        <meta name="description" content="Создание виджета для сообщества ВКонтакте">
        <meta name="keywords" content="Sergei Sokolov,ВК,виджет,конструктор">
        <meta name="robots" content="noindex,nofollow">
        
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    </head>
    
    <body>
    	<div class="container">
    		<h3>Виджет для сообщества ВК</h3>
    		
    		<div id="b-alerts"></div>
    		
    		<div class="form-group">
    			<button id="btn-permission" class="btn btn-primary" type="button">Дать разрешение</button>
    		</div>
    
    		<div class="form-group">
    			<label for="in-type">Тип виджета:</label>
    			<select class="form-control" id="in-type">
    				<option value="text">text</option>
    				<option value="list">list</option>
    				<option value="table">table</option>
    				<option value="tiles">tiles</option>
    				<option value="compact_list">compact_list</option>
    				<option value="cover_list">cover_list</option>
    				<option value="match">match</option>
    				<option value="matches">matches</option>
    			</select>
    		</div>
    		
    		<div class="form-group">
    			<label for="in-code">Код виджета:</label>
    			<textarea rows="7" class="form-control" id="in-code">return {
    "title": "Цитата",
    "text": "Текст цитаты"
    };</textarea>
    		</div>
    
    		<button id="btn-preview" class="btn btn-primary" type="button">Предпросмотр виджета</button>
    				
    	</div><!-- /.container -->
    	
    	
    	
    
    	<!-- Bootstrap JavaScript -->
      <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
    	<!-- /Bootstrap JavaScript -->
    	
    	<!-- main script -->
    	<script>
    		function onReady() {
    
    			// Слушать события предпросмотра виджета 
    			VK.addCallback('onAppWidgetPreviewFail', function(e){
    				console.error('onAppWidgetPreviewFail', e);
    				showAlert('warning', 'onAppWidgetPreviewFail');
    			});
    			
    			VK.addCallback('onAppWidgetPreviewCancel', function(e){
    				console.error('onAppWidgetPreviewCancel', e);
    				showAlert('info', 'onAppWidgetPreviewCancel');
    			});
    			
    			VK.addCallback('onAppWidgetPreviewSuccess', function(e){
    				console.log('onAppWidgetPreviewSuccess', e);
    				showAlert('success', 'onAppWidgetPreviewSuccess');
    			});
    			
    			// События нажатия на кнопки
    			$('#btn-permission').on('click', function(){
    				console.log('showGroupSettings');
    				VK.callMethod("showGroupSettingsBox", 64);
    			});
    			
    			$('#btn-preview').on('click', function(){
    				var type = $('#in-type').val(),
    				  code = $('#in-code').val()
    			  ;
    				
    				console.log('showAppWidgetPreviewBox', {type: type, code:code});
    				VK.callMethod("showAppWidgetPreviewBox", type, code);
    			});
    
    		}
    
    
    		function showAlert(className, text) {
    			var html = [
    				'<div class="alert alert-dismissible alert-'+className+'" role="alert">',
    					text,
    				'</div>',
    			].join('\n');
    			$('#b-alerts').append(html);
    		}
    	</script>
    	<!-- /main script -->
    	
    
    	<!-- VK scripts -->
    	<script src="https://vk.com/js/api/xd_connection.js?2"  type="text/javascript"></script>
    	
    	<script type="text/javascript">
    	  VK.init(function() {
    	     // API initialization succeeded
    	     onReady();
           
    	  }, function() {
    	     // API initialization failed
    	     // Can reload page here
    	     console.error('VK init error', arguments);
    		}, '5.74');
    	</script>
    	<!-- /VK scripts -->
    
    </body>
    </html>


    Какие бывают типы виджетов см. на странице документации по объекту appWidget.

    Какой конкретно шаг в этом сценарии у вас не получился?
    Ответ написан
  • Что не так с php-скриптом для VK API?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Разбирайте ответ от ВК, вполне возможно, что там содержится описание ошибки.

    Вместо
    printf('Success');
    exit;


    надо что-то типа
    $decoded = json_decode($query);
    if(!$decoded) {
      printf("ВК вернул невообразимую фигню: %s", $query);
    }
    else if( $decoded->error) {
      printf("Ошибка %d: %s\n", $decoded->error->error_code, $decoded->error->error_msg);
    } else if( $decoded->response) {
      printf("Пост опубликован с id %s\n", $decoded->response);
    }
    exit();


    Upd. возможно, дело в размещаемом сообщении и сurl. Попробуйте вместо CURLOPT_POSTFIELDS => array( ...
    сделать так:
    CURLOPT_POSTFIELDS     =>  http_build_query( array( ... ))
    Ответ написан
    Комментировать
  • Как сделать круговой счетчик чисел на js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Наверное, вам понадобится имитировать движение: без этого смотреться будет как медленно щелкающие значения.
    Для имитации движения нужно создавать размытие движения (motion blur) – в любой отдельный кадр видно не четкое значение, а размытое вдоль вектора движения.

    Отображаемые на экране кадры как бы идут слишком медленно, чтобы уместить все происходящие события, поэтому на один кадр накладывается несколько событий: число появилось вверху, проехало расстояние X, исчезло внизу, появилось следующее число, успело проехать пол-экрана. Всё это "засвечивает" всего один отображаемый кадр, на котором числа выглядят размазнно. Первое просто оставляет след во всю высоту, второе в пол-высоты.

    Как я понял, вам потребуется создать серию таких состояний:
    1. все смазано
    2. смазанно, но видно более ли менее значение 1 из 3
    3. все смазано
    4. смазанно, но читается значение 2 из 3
    5. все смазано
    6. смазанно, но читается значение 3 из 3

    Кадры для "всё смазано" можно заготовить заранее. Кадры с видимостью определённых значений генерить заранее наложением на полностью смазанные нескольких близких положений видимого числа.
    Ответ написан
    Комментировать
  • Как в JS преобразовать число 9.75e-8 в нормальное 0.000000975?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Например, так:
    function noExp(n){
        var data= String(n).split(/[eE]/);
        if(data.length== 1) return data[0]; 
    
        var  z= '', sign= this<0? '-':'',
        str= data[0].replace('.', ''),
        mag= Number(data[1])+ 1;
    
        if(mag<0){
            z= sign + '0.';
            while(mag++) z += '0';
            return z + str.replace(/^\-/,'');
        }
        mag -= str.length;  
        while(mag--) z += '0';
        return str + z;
    }
    
    noExp(n) // String "0.0000000975"

    via
    Ответ написан
    Комментировать
  • Почему ВК api возвращает ошибку Error 5: User authorization failed: no access_token passed?

    sergiks
    @sergiks Куратор тега ВКонтакте
    ♬♬
    Стоит ознакомиться с API ВКонтакте по их статье.

    Ваше сообщение об ошибке однозначно указывает на её причину: User authorization failed: no access_token passed. – не авторизовать пользователя, выполняющего запрос по причине отсутствия access_token'а (ключа доступа).

    Для выполнения friends.get() требуется ключ ("access_token") либо сервисный – из настроек созданного вами Приложения ВК; либо пользователя – полученный в результате диалога авторизации пользователя.

    Также обязательно стало указывать используемую версию API, параметр v. Сейчас актуальная версия 5.74

    Чтобы просто попробовать, создайте приложение типа standalone и скопируйте из его Настроек значение Сервисного ключа:
    скрин
    5af6a32ecd7c0965325530.png

    В итоге ваш запрос будет выглядеть примерно так:
    https://api.vk.com/method/friends.get?user_id=babegone&v=5.74&access_token=supersecretsupersecret
    Ответ написан
    6 комментариев
  • Что лучше использовать для авторизации пользователей cookie или сессии?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Сессии чаще всего держатся на cookie: с каждым запросом браузер передает куку с идентификатором сессии, и php вытаскивает из своего хранилища – файлов, Redis, базы данных, как настроете – сессионные данные для этого id.

    Т.е. различие в том, где хранить сами данные сессии: на сервере или на клиенте.

    Всё, что приходит с клиента можно подделать. Поэтому лучше использовать сессии.
    Ответ написан
    3 комментария