• Для чего нужен составной ключ в mysql?

    flapflapjack
    @flapflapjack
    на треть я прав
    У меня например есть таблица "права доступа".

    access (id,user_id,access_mode)
    У одного пользователя не может быть два раза одно и тоже значение access_mode ( зачем допускать пользователя 2 раза к одному и тому же разделу сайта?)

    Потому я использую двойной ключ (user_id,access_mode)
    Ответ написан
    9 комментариев
  • Как вытащить значения из всех под-элементов div'a?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const elementNames = Array.from(
      document.querySelectorAll('#spisok > div > p > br'),
      n => n.nextSibling.textContent.trim()
    );
    Ответ написан
    2 комментария
  • Как изучать vk.api?

    hottabxp
    @hottabxp
    Сначала мы жили бедно, а потом нас обокрали..
    В vk.com самое простое api в мире. Если вы не можете в нем разобраться, значит вам еще рано писать ботов. Вообще без знания основ(как показывает практика) писать ботов - это плохо. Возвращайтесь в самое начало и перечитывайте книги для начинающих с обязательной практикой.
    Ответ написан
    3 комментария
  • Как будет выглядеть код на чистом js?

    Kozack
    @Kozack Куратор тега JavaScript
    Thinking about a11y
    Ответ написан
    Комментировать
  • Что за ошибка с токеном?

    Вы объявляете переменную token, а в конструктор передаёте строку 'token'
    Ответ написан
    7 комментариев
  • Не могу разобраться в функциях?

    @d-sem
    function exec() {
      return other();
    }
    
    function other() {
      return ["cтрока","строка"]
    }
    Ответ написан
    Комментировать
  • Не могу разобраться в функциях?

    z80b
    @z80b
    Frontend
    other() {
      return [cтрока, строка]
    }
    exec() {
      return other();
    }
    Ответ написан
    Комментировать
  • Как сделать скошенные углы у блока?

    hzzzzl
    @hzzzzl
    псевдо, или просто в еще один див положить с таким же клип-патхом

    Ответ написан
    Комментировать
  • Не работает форма на openserver WordPress?

    @Asokr
    Это ничего вам не даст
    bloginfo('template_directory');
    https://wp-kama.ru/function/bloginfo

    Используйте
    get_bloginfo('template_url');
    или
    get_template_directory_uri()

    https://wp-kama.ru/function/get_template_directory_uri
    Ответ написан
    7 комментариев
  • Лучший учебник по дискретной математике на русском?

    https://www.ozon.ru/context/detail/id/4644853/
    Род Хаггарти - Дискретная математика для программистов
    Ответ написан
    Комментировать
  • Как удалить уволенного сотрудника из всех репозиториев GitHub?

    @Flying
    Если у вас аккаунт организации - то там всё просто: На основной странице организации вкладка People, дальше слева выбираете либо Members либо Outside collaborators, там выбираете нужного человека и слева внизу будет кнопка "Remove from all repositories".

    Если же у вас просто личный аккаунт - то там такого не предполагается (что естественно).

    Возможно вам стоит рассмотреть вариант перевода вашего аккаунта в аккаунт организации (Settings -> Organisations -> Transform account) если по факту это всё равно организация. Конечно в этом случае поменяется схема биллинга, но GitHub недавно сильно снизил цены для GitHub for Teams так что вполне можно пользоваться.
    Ответ написан
  • Как стать топовым WEB разработчиком?

    approximate_solution
    @approximate_solution
    JS Developer. Angular\React\Vue\Ember
    стать топовым WEB разработчиком на фрилансе/удаленке?

    Сразу возникает вопрос, где та оценка качества по которой вы хотите стать топ разработчиком. Вы берете одну из самых низкопороговых ниш, и пытаетесь стать "царем горы".
    Знаю HTML, CSS, Bootstrap 3,4, верстал на них, сейчас освоил FlexBox, знаю как адаптивно верстать.

    С таким даже на работу не берут, без знания хотя бы js\php - всё сложно, будете перебиваться мелкими заказами и демпинговать.
    Желание делать сайты под ключ, дизайны сайтов, приложений и разработка.

    Готовьтесь к огромной конкуреции среди таких же "топовых разработчиков"

    Как думаете все вместе реально круто освоить и стать хорошим разработчиком сайтов от дизайна до верстки и запуска сайта, так скажем?

    Вы опоздали лет на 10, когда люди с Вашими навыками делали достаточно неплохие деньги.

    Сейчас неплохие деньги будет делать тот, кто 10 лет нарабатывал своё портфолио, обзавелся клиентами, и чем ваши навыки в виде "знаю чуток, верстал на них, сейчас освоил flexbox" - рынку Вы с такими темпами пригодитесь лет через 5, когда освоите пару фреймворков, либо 4-5 cms + php.
    Ответ написан
    47 комментариев
  • Как выбрать медиа запросы?

    ArsenyMatytsyn
    @ArsenyMatytsyn Куратор тега CSS
    Руководитель frontend направления, предприниматель
    1. Mobile first → (mIN-width: 767px) более рузумен. Скорее единственно подходящий подход.
    2. 768 макета вполне хватает для покрытия большинства планшетных отрисовок вплоть до десктопа. Можно и 1024 вставить, как переходный, но в целом от него чаще проблемы.
    3. Верхняя планка, ИМХО, задрана, для десктопа минимальный должен быть не менее 1366, иначе многие владельцы компухтеров получат верстку для планшета.
    Ответ написан
    3 комментария
  • Укрепить знания PHP велосипедом или через фреймфорк?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ответ однозначный по двум причинам:

    В принципе, смогу построить mvc-приложение.

    Что означает "не могу". А вот фрейморк как раз таки тебе и покажет, как на самом деле выглядит мвц приложение.

    но в последующем обязательно будет расширяться и усложняться.

    Собственно, весь смысл фрейморков именно на этом этапе и проявляется.

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

    Vamp
    @Vamp
    Для начала необходимо разделить сайты друг от друга физически. Сами скрипты сайта, временные файлы и файлы сессий.

    Например, структура может быть такая:
    /var/www
      + toster.ru
      |  + site
      |  + sessions
      |  + temp
      + example.com
      |  + site
      |  + sessions
      |  + temp
      + остальные сайты


    В папке site расположены скрипты сайта. Обычно эта папка (или одна из вложенных) является document root сайта.

    В sessions находятся файлы сессий посетителей сайта. Если их не разделять, то взлом одного сайта автоматически дискредитирует сессии всех пользователей остальных сайтов. То есть, взломав example.com, можно стырить сессию администратора toster.ru. Путь к этой папке настраивается директивой session.save_path.

    А в temp находятся временные файлы, загружаемые пользователями через html формы (директива upload_tmp_dir). Туда же неплохо направить и остальные временные файлы, генерируемые функциями tmpfile(), tempnam(), самостоятельным образом (используя результат функции sys_get_temp_dir() для построения пути) или любой другой функцией, которая использует системную временную директорию. К сожалению, директива sys_temp_dir, ответственная за это, появилась только в php 5.5.0. Если у вас более ранняя версия, тогда нужно учитывать момент, что сайты могут ходить в /tmp и нельзя блокировать доступ к этой папке.

    ---

    Далее необходимо настроить нормальные права доступа. Часто в интернете можно видеть советы "делайте chmod 777 на всё". Так делать нельзя. Подобные права доступа как раз наихудшим образом сказываются на безопасности, потому что дают возможность отредактировать любой скрипт на сайте и встроить маленький бэкдор в самый незаметный скрипт, принадлежащий CMS. Надежно избавиться от такого довеска можно будет только полной переустановкой CMS. Или можно загнать весь сайт в систему контроля версий, как предложил Максим Гречушников, и одной командой узнать какие скрпиты были заражены. Тем не менее, одно другое не исключает. Система контроля версий позволит выявить заражение постфактум, а нормальные права не дадут возможности заразить файл в принципе.

    Я рекомендую на папки устанавливать права 755, а на файлы 644. При этом, владельцем всех папок и файлов должен быть кто угодно, но не пользователь, из-под которого запущен веб-сервер или php (например, пользователь, под которым вы сами заходите на сервер по ssh). Но такие права на всё устанавливать тоже нельзя. Сайт в процессе своей работы может генерировать свои временные файлы (например, кешировать что-то в файл, компилировать шаблоны, хранить какие-нибудь настройки), поэтому для папок, в которые сайт может что-то записать, права должны быть другие. Вот здесь уже можно ставить 777 для папок и 666 для файлов. Это довольно кропотливая работа, потому что у каждого сайта (особенно если они на разных CMS) свои папки и часто определение таких папок нетрвиально.

    И права доступа не решают всех проблем. Злоумышленник может встроить вредоносный код в скомпилированный шаблон или отравить кеш. Тогда не помогут ни права (так как для нормальной работы сайту нужно иметь права на запись в такие файлы), ни система контроля версий (так как подобные файлы слишком часто меняются и, как правило, не хранятся в репозитории). Хотя надо сказать, этот способ внедрения сложнее и недолговечнее, чем встраивание в нормальный скрипт.

    И ещё автоматическое обновление сайта перестанет работать. Если CMS позволяет обновить себя через кнопку в веб-интерфейсе админки, то такое обновление не будет работать, так как права доступа не разрешают веб-серверу модифицировать скрипты. Обновлять скрипты теперь можно только вручную от имени пользователя, которому принадлежат все файлы. Безопасность и удобство - разные концы одной палки.

    Даже с учётом всех недостатков - нормально настроенные права доступа на файлы и папки значительно сокращают вектор возможных атак. Так что обязательно разберитесь с этим вопросом.

    ---

    После раскидывания сайтов по своим папкам и настройки прав, необходимо ограничить доступ сайтов друг к другу. Проще всего это сделать настройкой php директивы open_basedir. Эта директива определяет список директорий, внутри которых (а так же во всех вложенных папках) скрипты могут читать и писать. Доступ за пределы этих директорий будет пресекаться. То есть нужно каждому сайту прописать в open_basedir путь к своей папке и к /tmp (если версия php < 5.5.0 и нельзя установить sys_temp_dir).

    Для Apache с mod_php конфигурация прописывается в httpd.conf:

    <VirtualHost *:80>
      ServerName example.com
      php_admin_value open_basedir /var/www/example.com/:/tmp/
      php_admin_value upload_tmp_dir /var/www/example.com/temp/
      php_admin_value sys_temp_dir /var/www/example.com/temp/
      php_value session.save_path /var/www/example.com/sessions/
    </VirtualHost>


    Для php-fpm в конец php.ini файла вписывается специальная секция, определяющая индивидуальную конфигурацию для каждого сайта:

    [HOST=example.com]
    open_basedir /var/www/example.com/:/tmp/
    upload_tmp_dir /var/www/example.com/temp/
    sys_temp_dir /var/www/example.com/temp/
    session.save_path /var/www/example.com/sessions/
    
    [HOST=toster.ru]
    ; конфиг для toster.ru и т.д.


    У open_basedir есть недостатки:

    1. Замедление файловых операций, так как необходимо проверить вхождение каждого открываемого файла в список open_basedir. Если проекты не highload, то некритично.
    2. Есть варианты обхода. Но их далеко не всегда удаётся эксплуатировать. Тем более они закрываются со временем в новых версиях php.
    3. Realpath cache не работает вместе с включенной open_basedir.

    ---

    Есть вариант запускать каждый сайт от своего пользователя. В apache это делается опцией AssignUserId. В php-fpm - отдельной конфигурацией pool. Но в любом случае нужно для каждого сайта создавать не только отдельного юзера, но и группу. При этом права на основную папку сайта (/var/www/example.com) должны быть 750, а группа должна соответствовать той, от которой будет запускаться процесс apache (или пул php-fpm), ответственный за обслуживание сайта.

    Проще показать на примере. После имени файла я буду указывать права, владельца и группу в формате (права, владелец:группа)
    /var/www         (755, root:root)
      + toster.ru    (750, my_user:toster)
      |  + site      (755, my_user:toster)
      |  + sessions  (777, my_user:toster)
      |  + temp      (777, my_user:toster)
      + example.com  (750, my_user:example)
      |  + site      (755, my_user:example)
      |  + sessions  (777, my_user:example)
      |  + temp      (777, my_user:example)
      + остальные сайты - всё аналогично


    my_user - это пользователь, под которым ни в коем случае нельзя запускать веб-сервер и php. Это может быть ваш собственный пользователь, под которым вы заходите на сервер по ssh. В этом случае у вас будут все права на сайт, а у сайта только необходимый минимум.

    <VirtualHost *:80>
      ServerName example.com
      AssignUserId exapmle example
    </VirtualHost>
    <VirtualHost *:80>
      ServerName toster.ru
      AssignUserId toster toster
    </VirtualHost>


    Разумеется, в системе должны быть заранее созданы пользователи с именами toster, example и с одноимёнными основными группами.

    Вобщем, рекомендую более подробно ознакомиться с системой прав и пользователей в линуксе. Пригодится всегда.

    ---

    Более сложным и предпочтительным вариантом является упаковка каждого сайта в свой отдельный виртуальный контейнер lxc/docker. Я не смогу в двух словах описать как это добро настраивать, но эффект будет такой, как будто каждый сайт работает на своём собственном VPS сервере.

    ---

    Ещё немного про базу. Для доступа к базе у каждого сайта должен быть свой собственный логин с паролем. Причем, доступ должен ограничиваться исключительно той базой, в которой находятся данные сайта. И права должны быть не все подряд, а только SELECT, INSERT, UPDATE, DELETE. В редких случаях CMS может самостоятельно создавать таблицы для своих нужд в процессе своей работы (не в процессе первичной установки). В этом случае можно добавить права CREATE, ALTER, INDEX юзеру этого сайта. Иногда бывает в базе есть какие-то процедуры/функции. Для их вызова требуются права EXECUTE.

    ---

    Безопасность - дело большое и очень разнообразное. И уж точно не простое. Всё что я здесь написал - это далеко не полный список. Есть ещё настройки уровня операционной системы (особенно фаервол) и прочего установленного в системе софта. Так же отдельным пунктом идёт система мониторинга и оповещения, которые почему-то никто не делает - не считают нужным разбираться ещё и в этом. Так что если у вас нет хорошего админа в запасе, то проще будет заказать услугу администрирования прямо у того же хостера, у которого вы арендуете VPS. Или найти админа-фрилансера. Или же перевезти сайты на shared хостинг, где администрирование уже включено в ценник, да и сам переезд хостеры часто предлагают сделать бесплатно силами своих админов.
    Ответ написан
    Комментировать
  • Засечь время скачивания файла из вк на python?

    kshnkvn
    @kshnkvn
    yay ✌️ t.me/kshnkvn
    import urllib.request
    import time
    
    url = "https://любаяпикча.jpg"
    start_time = int(round(time.time() * 1000))
    img = urllib.request.urlopen(url).read()
    out = open("img.jpg", "wb")
    out.write(img)
    out.close
    end_time = int(round(time.time() * 1000)) - start_time
    print(end_time)
    Ответ написан
    Комментировать
  • Как валидно настроить права для nginx и php-fpm?

    Sanes
    @Sanes
    Nginx тут не при чем. Это настраивается в пуле PHP-FPM.
    PHP-FPM

    [{{ username }}]
    user = {{ username }}
    group = {{ username }}
    listen = /var/run/php/php{{ php }}-fpm-{{ username }}.sock
    listen.owner = www-data
    listen.group = www-data
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    chdir = /
    ;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
    ;php_flag[display_errors] = off
    php_admin_value[error_log] = /var/www/{{ username }}/logs/fpm-php.{{ username }}.log
    ;php_admin_flag[log_errors] = on
    ;php_admin_value[memory_limit] = 32M
    php_admin_value[upload_max_filesize] = 100M
    php_admin_value[post_max_size] = 100M
    php_admin_value[open_basedir] = /var/www/{{ username }}/
    php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source,stream_set_write_buffer,stream_socket_sendto,highlight_file,com_load_typelib
    php_admin_value[upload_tmp_dir] = /var/www/{{ username }}/tmp
    php_admin_value[soap.wsdl_cache_dir] = /var/www/{{ username }}/tmp

    Nginx

    server {
    	listen 80;
    	#listen [::]:80 default_server ipv6only=on;
    
    	root /var/www/{{ username }}/www;
    	index index.php index.html index.htm;
    
    	server_name {{ domain }};
    
    	location / {
    		try_files $uri $uri/ =404;
            if (!-e $request_filename) {
            rewrite ^/(.*)$ /index.php?q=$1 last;
    	    }
    	}
    
    	location ~ \.php$ {
    		include snippets/fastcgi-php.conf;
    		fastcgi_split_path_info ^(.+\.php)(/.+)$;
    		fastcgi_pass unix:/run/php/php{{ php }}-fpm-{{ username }}.sock;
    		include fastcgi_params;
    	}
    	client_max_body_size 100M;
    }

    Ответ написан
  • Что лучше использовать для корзины покупок?

    php666
    @php666
    PHP-макака
    Но есть люди которые запрещают их использование путем установок некоторых расширении в браузеры.
    это их проблемы

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