Исходники Facebook просочились в Сеть

    Вы давно хотели увидеть исходный код одного из самых успешных проектов Веб 2.0? Ну вот, сегодня как раз тот день, когда вы можете посмотреть на работу «лучших PHP-программистов мира».

    Вчера из-за небольшого глюка на сервере Facebook исходный код первой страницы этого социального сервиса стал виден небольшому количеству пользователей. Самые умные из них сделали копию, так что сейчас исходники выложены на всеобщее обозрение.

    Компания Facebook уже подтвердила утечку информации, так что это настоящий код, а не подделка.

    Впрочем, ничего особенного в коде нет, это стандартный PHP-код. Независимые программисты уже давно изучили и Facebook, и другие сервисы Веб 2.0, так что на чёрном рынке вы можете без проблем купить клон того же Facebook за $200.

    include_once $_SERVER['PHP_ROOT'].'/html/init.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/home.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/requests.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/feed/newsfeed.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/poke.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/share.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/orientation.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/feed/newsfeed.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/mobile/register.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/forms_lib.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/contact_importer/contact_importer.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/feed/util.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/hiding_prefs.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/abtesting.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/friends.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/statusupdates.php';
    
    // lib/display/feed.php has to be declared here for scope issues.
    // This keeps display/feed.php cleaner and easier to understand.
    include_once $_SERVER['PHP_ROOT'].'/lib/display/feed.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/monetization_box.php';
    
    // require login
    $user = require_login();
    print_time('require_login');
    param_request(array( 'react' => $PARAM_EXISTS));
    
    // Check and fix broken emails
    // LN - disabling due to excessive can_see dirties and sets when enabled.
    //check_and_fix_broken_emails($user);
    
    // migrate AIM screenname from profile to screenname table if needed
    migrate_screenname ($user);
    
    // homepage announcement variables
    $HIDE_ANNOUNCEMENT_BIT = get_site_variable('HIDE_ANNOUNCEMENT_BIT');
    $HIDE_INTRO_BITMASK = get_site_variable('HIDE_INTRO_BITMASK');
    
    // redirects
    if (is_sponsor_user()) {
    redirect('bizhome.php', 'www');
    }
    
    include_once $_SERVER['PHP_ROOT'].'/lib/mesg.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/invitetool.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/grammar.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/securityq.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/events.php';
    include_once $_SERVER['PHP_ROOT'].'/lib/rooster/stories.php';
    
    // todo: password confirmation redirects here (from html/reset.php),
    // do we want a confirmation message?
    
    param_get_slashed(array(
    'feeduser' => $PARAM_INT, //debug: gets feed for user here
    'err' => $PARAM_STRING, // returning from a failed entry on an orientation form
    'error' => $PARAM_STRING, // an error can also be here because the profile photo upload code is crazy
    'ret' => $PARAM_INT,
    'success' => $PARAM_INT, // successful profile picture upload
    'jn' => $PARAM_INT, // joined a network for orientation
    'np' => $PARAM_INT, // network pending (for work/address network)
    'me' => $PARAM_STRING, // mobile error
    'mr' => $PARAM_EXISTS, // force mobile reg view
    'mobile' => $PARAM_EXISTS, // mobile confirmation code sent
    'jif' => $PARAM_EXISTS, // just imported friends
    'ied' => $PARAM_STRING, // import email domain
    'o' => $PARAM_EXISTS, // first time orientation, passed on confirm
    'verified' => $PARAM_EXISTS)); // verified mobile phone
    
    param_post(array(
    'leave_orientation' => $PARAM_EXISTS,
    'show_orientation' => $PARAM_INT, // show an orientation step
    'hide_orientation' => $PARAM_INT)); // skip an orientation step
    
    // homepage actions
    if ($req_react && validate_expiring_hash($req_react, $GLOBALS['url_md5key'])) {
    $show_reactivated_message = true;
    } else {
    $show_reactivated_message = false;
    }
    tpl_set('show_reactivated_message', $show_reactivated_message);
    
    
    // upcoming events
    events_check_future_events($user); // make sure big tunas haven't moved around
    $upcoming_events = events_get_imminent_for_user($user);
    
    // this is all stuff that can be fetched together!
    $upcoming_events_short = array();
    obj_multiget_short(array_keys($upcoming_events), true, $upcoming_events_short);
    $new_pokes = 0;
    //only get the next N pokes for display
    //where N is set in the dbget to avoid caching issues
    $poke_stats = get_num_pokes($user);
    get_next_pokes($user, true, $new_pokes);
    $poke_count = $poke_stats['unseen'];
    
    $targeted_data = array();
    home_get_cache_targeted_data($user, true, $targeted_data);
    $announcement_data = array();
    home_get_cache_announcement_data($user, true, $announcement_data);
    $orientation = 0;
    orientation_get_status($user, true, $orientation);
    $short_profile = array();
    profile_get_short($user, true, $short_profile);
    // pure priming stuff
    privacy_get_network_settings($user, true);
    $presence = array();
    mobile_get_presence_data($user, true, $presence);
    feedback_get_event_weights($user, true);
    // Determine if we want to display the feed intro message
    $intro_settings = 0;
    user_get_hide_intro_bitmask($user, true, $intro_settings);
    $user_friend_finder = true;
    contact_importer_get_used_friend_finder($user, true, $used_friend_finder);
    $all_requests = requests_get_cache_data($user);
    // FIXME?: is it sub-optimal to call this both in requests_get_cache_data and here?
    $friends_status = statusupdates_get_recent($user, null, 3);
    memcache_dispatch(); // populate cache data
    
    // Merman's Admin profile always links to the Merman's home
    if (user_has_obj_attached($user)) {
    redirect('mhome.php', 'www');
    }
    
    if (is_array($upcoming_events)) {
    foreach ($upcoming_events as $event_id => $data) {
    $upcoming_events[$event_id]['name'] = txt_set($upcoming_events_short[$event_id]['name']);
    }
    }
    
    tpl_set('upcoming_events' , $upcoming_events);
    
    // disabled account actions
    $disabled_warning = ((IS_DEV_SITE || IS_QA_SITE) && is_disabled_user($user));
    tpl_set('disabled_warning', $disabled_warning);
    
    // new pokes (no more messages here, they are in the top nav!)
    if (!user_is_guest($user)) {
    tpl_set('poke_count' , $poke_count);
    tpl_set('pokes' , $new_pokes);
    }
    
    // get announcement computations
    tpl_set('targeted_data' , $targeted_data);
    tpl_set('announcement_data' , $announcement_data);
    
    
    // birthday notifications
    tpl_set('birthdays' , $birthdays = user_get_birthday_notifications($user, $short_profile));
    tpl_set('show_birthdays' , $show_birthdays = (count($birthdays) || !$orientation));
    
    // user info
    tpl_set('first_name' , user_get_first_name(txt_set($short_profile['id'])));
    tpl_set('user' , $user);
    
    // decide if there are now any requests to show
    $show_requests = false;
    foreach ($all_requests as $request_category) {
    if ($request_category) {
    $show_requests = true;
    break;
    }
    }
    tpl_set('all_requests', $show_requests ? $all_requests : null);
    
    $permissions = privacy_get_reduced_network_permissions($user, $user);
    
    // status
    $user_info = array('user' => $user,
    'firstname' => user_get_first_name($user),
    'see_all' => '/statusupdates/?ref=hp',
    'profile_pic' => make_profile_image_src_direct($user, 'thumb'),
    'square_pic' => make_profile_image_src_direct($user, 'square'));
    
    if (!empty($presence) && $presence['status_time'] > (time() - 60*60*24*7)) {
    $status = array('message' => txt_set($presence['status']),
    'time' => $presence['status_time'],
    'source' => $presence['status_source']);
    } else {
    $status = array('message' => null, 'time' => null, 'source' => null);
    }
    tpl_set('user_info', $user_info);
    
    tpl_set('show_status', $show_status = !$orientation);
    tpl_set('status', $status);
    tpl_set('status_custom', $status_custom = mobile_get_status_custom($user));
    tpl_set('friends_status', $friends_status);
    
    // orientation
    if ($orientation) {
    if ($post_leave_orientation) {
    orientation_update_status($user, $orientation, 2);
    notification_notify_exit_orientation($user);
    dirty_user($user);
    redirect('home.php');
    } else if (orientation_eligible_exit(array('uid'=>$user)) == 2) {
    orientation_update_status($user, $orientation, 1);
    notification_notify_exit_orientation($user);
    dirty_user($user);
    redirect('home.php');
    }
    }
    
    // timezone - outside of stealth, update user's timezone if necessary
    $set_time = !user_is_alpha($user, 'stealth');
    tpl_set('timezone_autoset', $set_time );
    if ($set_time) {
    $daylight_savings = get_site_variable('DAYLIGHT_SAVINGS_ON');
    tpl_set('timezone', $short_profile['timezone'] - ($daylight_savings ? 4 : 5) );
    }
    
    // set next step if we can
    if (!$orientation) {
    user_set_next_step($user, $short_profile);
    }
    
    // note: don't make this an else with the above statement, because then no news feed stories will be fetched if they're exiting orientation
    if ($orientation) {
    extract(orientation_get_const());
    
    require_js('js/dynamic_dialog.js');
    require_js('js/suggest.js');
    require_js('js/typeahead_ns.js');
    require_js('js/suggest.js');
    require_js('js/editregion.js');
    require_js('js/orientation.js');
    require_css('css/typeahead.css');
    require_css('css/editor.css');
    
    if ($post_hide_orientation && $post_hide_orientation <= $ORIENTATION_MAX) {
    $orientation['orientation_bitmask'] |= ($post_hide_orientation * $ORIENTATION_SKIPPED_MODIFIER);
    orientation_update_status($user, $orientation);
    } else if ($post_show_orientation && $post_show_orientation <= $ORIENTATION_MAX) {
    $orientation['orientation_bitmask'] &= ~($post_show_orientation * $ORIENTATION_SKIPPED_MODIFIER);
    orientation_update_status($user, $orientation);
    }
    
    $stories = orientation_get_stories($user, $orientation);
    switch ($get_err) {
    case $ORIENTATION_ERR_COLLEGE:
    $temp = array(); // the affil_retval_msg needs some parameters won't be used
    $stories[$ORIENTATION_NETWORK]['failed_college']=affil_retval_msg($get_ret, $temp, $temp);
    break;
    case $ORIENTATION_ERR_CORP:
    $temp = array();
    // We special case the network not recognized error here, because affil_retval_msg is retarded.
    $stories[$ORIENTATION_NETWORK]['failed_corp'] = ($get_ret == 70) ? 'The email you entered did not match any of our supported networks. ' .
    'Click here to see our supported list. ' .
    'Go here to suggest your network for the future.'
    : affil_retval_msg($get_ret, $temp, $temp);
    break;
    }
    
    // photo upload error
    if ($get_error) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_PROFILE]]['upload_error'] = pic_get_error_text($get_error);
    }
    // photo upload success
    else if ($get_success == 1) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_PROFILE]]['uploaded_pic'] = true;
    // join network success
    } else if ($get_jn) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['joined'] = array(
    'id' => $get_jn,
    'name' => network_get_name($get_jn));
    // network join pending
    } else if ($get_np) {
    
    $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['join_pending'] = array(
    'id' => $get_np,
    'email' => get_affil_email_conf($user, $get_np),
    'network' => network_get_name($get_np));
    // just imported friend confirmation
    } else if ($get_jif) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['just_imported_friends'] = true;
    $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['domain'] = $get_ied;
    }
    
    // Mobile web API params
    if ($get_mobile) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['sent_code'] = true;
    $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['view'] = 'confirm';
    }
    if ($get_verified) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['verified'] = true;
    }
    if ($get_me) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['error'] = $get_me;
    }
    if ($get_mr) {
    $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['view'] = 'register';
    }
    
    if (orientation_eligible_exit($orientation)) {
    tpl_set('orientation_show_exit', true);
    }
    tpl_set('orientation_stories', $stories);
    
    //if in orientation, we hide all feed intros (all 1's in bitmask)
    $intro_settings = -1;
    
    }
    tpl_set('orientation', $orientation);
    
    // Rooster Stories
    if (!$orientation &&
    ((get_site_variable('ROOSTER_ENABLED') == 2) ||
    (get_site_variable('ROOSTER_DEV_ENABLED') == 2))) {
    $rooster_story_count = get_site_variable('ROOSTER_STORY_COUNT');
    if (!isset($rooster_story_count)) {
    // Set default if something is wrong with the sitevar
    $rooster_story_count = 2;
    }
    $rooster_stories = rooster_get_stories($user, $rooster_story_count, $log_omissions = true);
    if (!empty($rooster_stories) && !empty($rooster_stories['stories'])) {
    // Do page-view level logging here
    foreach($rooster_stories['stories'] as $story) {
    rooster_log_action($user, $story, ROOSTER_LOG_ACTION_VIEW);
    }
    tpl_set('rooster_stories', $rooster_stories);
    }
    }
    
    // set the variables for the home announcement code
    $hide_announcement_tpl = ($intro_settings | $HIDE_INTRO_BITMASK) & $HIDE_ANNOUNCEMENT_BIT;
    // if on qa/dev site, special rules
    $HIDE_INTRO_ON_DEV = get_site_variable('HIDE_INTRO_ON_DEV');
    if ((IS_QA_SITE || IS_DEV_SITE) && !$HIDE_INTRO_ON_DEV) {
    $hide_announcement_tpl = 0;
    }
    
    tpl_set('hide_announcement', $hide_announcement_tpl);
    if($is_candidate = is_candidate_user($user)) {
    tpl_set('hide_announcement', false);
    }
    $home_announcement_tpl = !$hide_announcement_tpl || $is_candidate ? home_get_announcement_info($user) : 0;
    tpl_set('home_announcement', $home_announcement_tpl);
    tpl_set('hide_announcement_bit', $HIDE_ANNOUNCEMENT_BIT);
    
    $show_friend_finder = !$orientation && contact_importer_enabled($user) && !user_get_hiding_pref($user, 'home_friend_finder');
    tpl_set('show_friend_finder', $show_friend_finder);
    if ($show_friend_finder && (user_get_friend_count($user) > 20)) {
    tpl_set('friend_finder_hide_options', array('text'=>'close',
    'onclick'=>"return clearFriendFinder()"));
    } else {
    tpl_set('friend_finder_hide_options', null);
    }
    
    $account_info = user_get_account_info($user);
    $account_create_time = $account_info['time'];
    
    tpl_set('show_friend_finder_top',
    !$used_friend_finder);
    
    tpl_set('user', $user);
    
    
    // MONETIZATION BOX
    $minimize_monetization_box = user_get_hiding_pref($user, 'home_monetization');
    $show_monetization_box = (!$orientation &&
    get_site_variable('HOMEPAGE_MONETIZATION_BOX'));
    tpl_set('show_monetization_box', $show_monetization_box);
    tpl_set('minimize_monetization_box', $minimize_monetization_box);
    
    if ($show_monetization_box) {
    $monetization_box_data = monetization_box_user_get_data($user);
    txt_set('monetization_box_data', $monetization_box_data);
    }
    
    
    // ORIENTATION
    if ($orientation) {
    $network_ids = id_get_networks($user);
    $network_names = multiget_network_name($network_ids);
    $in_corp_network = in_array($GLOBALS['TYPE_CORP'], array_map('extract_network_type', $network_ids));
    $show_corp_search = $in_corp_network ||
    get_age(user_get_basic_info_attr($user, 'birthday')) >= 21;
    $pending_hs = is_hs_pending_user($user);
    $hs_id = null;
    $hs_name = null;
    if ($pending_hs) {
    foreach (id_get_pending_networks($user) as $network) {
    if (extract_network_type($network['network_key']) == $GLOBALS['TYPE_HS']) {
    $hs_id = $network['network_key'];
    $hs_name = network_get_name($hs_id);
    break;
    }
    }
    }
    //$orientation_people = orientation_get_friend_and_inviter_ids($user);
    $orientation_people = array('friends' => user_get_all_friends($user),
    'pending' => array_keys(user_get_friend_requests($user)),
    'inviters'=> array(), // wc: don't show inviters for now
    );
    $orientation_info = array_merge($orientation_people,
    array('network_names' => $network_names,
    'show_corp_search' => $show_corp_search,
    'pending_hs' => array('hs_id'=>$hs_id,
    'hs_name'=>$hs_name),
    'user' => $user,
    ));
    tpl_set('orientation_info', $orientation_info);
    
    tpl_set('simple_orientation_first_login', $get_o); // unused right now
    }
    
    
    // Roughly determine page length for ads
    // first, try page length using right-hand panel
    $ads_page_length_data = 3 + // 3 for profile pic + next step
    ($show_friend_finder ? 1 : 0) +
    ($show_status ? ($status_custom ? count($friends_status) : 0) : 0) +
    ($show_monetization_box ? 1 : 0) +
    ($show_birthdays ? count($birthdays) : 0) +
    count($new_pokes);
    
    // page length using feed stories
    if ($orientation) {
    $ads_page_length_data = max($ads_page_length_data, count($stories) * 5);
    }
    tpl_set('ads_page_length_data', $ads_page_length_data);
    
    $feed_stories = null;
    if (!$orientation) { // if they're not in orientation they get other cool stuff
    // ad_insert: the ad type to try to insert for the user
    // (0 if we don't want to try an insert)
    $ad_insert = get_site_variable('FEED_ADS_ENABLE_INSERTS');
    
    $feed_off = false;
    
    if (check_super($user) && $get_feeduser){
    $feed_stories = user_get_displayable_stories($get_feeduser, 0, null, $ad_insert);
    } else if (can_see($user, $user, 'feed')) {
    $feed_stories = user_get_displayable_stories($user, 0, null, $ad_insert);
    } else {
    $feed_off = true;
    }
    
    // Friend's Feed Selector - Requires dev.php constant
    if (is_friendfeed_user($user)) {
    $friendfeed = array();
    $friendfeed['feeduser'] = $get_feeduser;
    $friendfeed['feeduser_name'] = user_get_name($get_feeduser);
    $friendfeed['friends'] = user_get_all_friends($user);
    tpl_set('friendfeed', $friendfeed);
    }
    
    $feed_stories = feed_adjust_timezone($user, $feed_stories);
    
    tpl_set('feed_off', $feed_off ? redirect('privacy.php?view=feeds', null, false) : false);
    }
    tpl_set('feed_stories', $feed_stories);
    
    render_template($_SERVER['PHP_ROOT'].'/html/home.phpt');
    Поддержать автора
    Поделиться публикацией

    Комментарии 53

      0
      Хочу заметить, что то нарушает копирайт facebook. Они уже начали рассылать официальные обращения убрать код к авторам блогов, в которых размещён этот код.
        0
        Думаете, они до сюда доберутся? ;)
          0
          Через google можно найти всех сразу:

          http://www.google.com/search?q=%22%2Flib%2Fsecurityq.php%22
        0
        Да и читать код в таком виде крайне не удобно.
          0
          А чего в нем интересного? Без остальных исходников он бесполезен.
            0
            А вдруг там есть system($_GET['super_hidden_backdoor']); ? :)
              0
              Интересного, там много, с точки зрения организации кода. Мне допустим было интересно посмотреть как разбили на модули, и есть ли MVC. Какой стиль программирования у "гигантов".
                0
                Стиль так себе.
            • НЛО прилетело и опубликовало эту надпись здесь
              +2
              Очень жаль, что «лучшии PHP-программисты мира» до сих пор пользуются функциональным подходом в программировании.
                0
                Я сам сейчас также пишу. Я был рад, что я не один. Хотя жду книжучку от SoftTime по ООП, чтобы тоже понять всю прелесть ООП.
                • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  Возможно, это сделано для увеличения производительности
                    0
                    Да уж.
                    0
                    а чем функциональный подход плох?
                      0
                      Как вы себе представляете поддержку большого проекта где все функции в одной области видимости (вобщем написано без ООП или хотябы неймспейсов). Это просто большая помойка.
                        0
                        Карамба! Ладно, ладно. Честно говоря, я не разбираюсь в подходах и не могу уверенно утверждать где функциональный подход, а где нет; не думаю, что когда все в одной куче --- это функциональный подход, все-таки это не очень удобно для программистов.

                        Там, где все в одной куче и ничего не разобрать --- там вообще подхода нет никакого.
                          0
                          Судя по успеху как то поддерживают.

                          Хотя код ужасный. Не верю что это их.
                        0
                        имелось в виду "процедурным подходом"? Функциональный подход ничем не хуже ООП, а в некоторых случаях и гораздо лучше.
                        +1
                        Хм, помоему, это ужасно - все в перемешку, сплошные if и else, циклы... Наверное, ООП спас бы «лучших PHP-программистов мира» :) Хотя, не мне судить, может быть им так легче эфективнее.
                        Странно, заметил я у себя такую особенность - чем больше смотрю на PHP-код (в особенности этот), тем больше мне нравится Python.
                          0
                          Можно подумать что в питоне подобную гадость не накодить. Разве что смотреться будет красивее за счет отсупов.
                          0
                          Самый бесполезный исходник, который я когда либо видел.
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              Этот пример обычно используется в учебных пособиях, где он небесполезен.
                            0
                            >так что на чёрном рынке вы можете без проблем купить клон того же Facebook за $200.
                            И как же это сделать? Что-то из профиля на блогспоте этого не видать.
                            • НЛО прилетело и опубликовало эту надпись здесь
                                0
                                В жизни не видел более ужасного кода.
                                  0
                                  Вы еще молодой, еще все спереди :)
                                    0
                                    Нет уж, спасибо :)

                                    Вообще конечно есть PHP-код куда более ужасный. Жаль, что его слишком много...
                                    0
                                    Даже не представляю, сколько нужно программеров, чтобы тащить такое чудо. Я бы поседел на пятый день работы над таким кодом :(
                                    0
                                    > код одного из самых успешных проектов Веб 2.0
                                    :) вот так сегодня на кухне посидели и решили "не успешный" :)
                                      –1
                                      Нереальное количество include. Даже страшно предположить сколько времени займет генерация этой страницы (считаю, что полсекунды - уже много). А если нагрузка сильная? Вообще капец? Я, конечно понимаю, что библиотеки нужно дробить по функциональному набору, но не до такой же степени. Все таки для фронтальной части можно немного свернуть все это хозяйство в кучу. Ну и кэширование не помешало-бы. А за утечку исходников сисадминам башку снести, чтоб за веб-сервером нормально следили. Мое мнение.
                                        0
                                        У facebook'a неслабая нагрузка, а работает.
                                          0
                                          "А работает" за аргумент не считаю. Сегодня работает, а завтра - нет.
                                            0
                                            уже который год работает :)
                                          0
                                          1. Я насчитал всего ли 25 инклюдов - это вполне реальное количество. Бывает и по 100 и по 200 в итоге - и неичего работает.
                                          2. Если бы вы присмотрелись, то уведели бы что кэширование там есть.
                                            0
                                            Смею предположить, что здесь собрались люди, занимающиеся PHP. Думаю, что все в курсе того, что при выполнении PHP сценария одна из самых тяжелых команды - include. Не потому ли она тяжелая, что серваку приходится двигать бошки над поверхностью диска в поисках нужных секторов (в случае подключения сценария)? Дак давайте же делать по 100 или 200 инклудов и смотреть, когда же у нас наступит предел возможностей сервера. Все правильно, уплочено и за RAID и за SCSI, нечего железу прохлаждаться, пусть пыхтит. Я понимаю - есть нормы и правила ведения сложных проетов, которые диктуют необходимость в четком структурировании кода. Но почему нельзя хотя бы задуматься о компромиссе и найти золотую середину между производительностью и ясностью?

                                            Осмелюсь подумать на эту тему. Потому что программист приходит на работу к 9 и уходит в 18 (к примеру). Потому что он знает, что ему заплатят н-ное количество тугриков в месяц и ни больше. И что он делает? Делает маскимально ясный и понятный код. Нет необходимости париться о тяжести кода, о нагрузке. Контора поставит н-ный сервак, сисадмины сделают кластер и все будет хорошо. Раньше люди писали код, потому что им это нравилось и было очень неплохо, если за это платили. Сейчас пишут код, потому что за это платят.

                                            Мы в разных лодках
                                              0
                                              самое интересное что ничего плохого по большому счету в этом нет. т.е. в такой ситуации нет недовольных:
                                              а) программист - он получает свои деньги, пишет плохой, но понятный ему код, может быть он и самнедоволен своим кодом, но если он пишет - значит его это устраивает
                                              б) пользователи продукта - им вообще пофиг какой там код - контора поставит n-ный сервак, и сколько там инклюдов пользователям уже не будет важно
                                              в) контора - на первый взгляд как раз им меньше всего выгодно такое положение дел, но... судя по капитализации того-же facebook их это совершенно не волнует. не волнует то что этот код требует бОльших мощностей, не волнует то что его сложнее повторно использовать. единственное что здесь важно - это скорость разработки в самом начале и возможность поддерживать (хотя-бы и с большими затратами) впоследствии

                                              а писать код "писали код, потому что им это нравилось и было очень неплохо, если за это платили", это хорошо, но это непрофессионально (хотя это вполне работает в Open Source, там действительно люди заботятся о качестве кода, но это немного другая тема)
                                                0
                                                Ребят, да вы что? какие обращения к дискам? ОС кеширует частоиспользуемые файлы, к которым обращаются, таким образом даже если каждый файл по киллобайт 50 то 20 - это около 1 мб, это все довольно удачно лежит в памяти и подгружается мгновенно. А если учитывать что данные куски инклудятся в большенстве их сценариев. Так что говорить о "тяжелости комманыд инклуд" это глупо.
                                                  0
                                                  Когда-нибудь интересовались назначением утилиты ab, которая входит в дистрибутив Apache? Советую сделать лабораторную работу. Для этого потребуется сервер под nix-системой с Apache и тестовым хостом. Попробуйте сделать тест кода с 20 инклудами и без них. Поупражняйтесь
                                                  и после этого сделаете выводы. На всякий случай нарисую команду

                                                  ./ab -n 500 -c 5 ваш_хост.ru/путь/

                                                  -n число запросов
                                                  -с число выполняющих запросы клиентов
                                                    0
                                                    -n количество запросов
                                                    -с количество конкурентных(одновременных) запросов

                                                    исходник:
                                                    /* include_once 'a.php';
                                                    include_once 'b.php';
                                                    include_once 'c.php';
                                                    include_once 'd.php';
                                                    include_once 'e.php';
                                                    include_once 'f.php';
                                                    include_once 'g.php';
                                                    include_once 'h.php';*/

                                                    function a(){
                                                    echo 'a';
                                                    }

                                                    function b(){
                                                    echo 'b';
                                                    }

                                                    function c(){
                                                    echo 'c';
                                                    }

                                                    function d(){
                                                    echo 'd';
                                                    }

                                                    function e(){
                                                    echo 'e';
                                                    }

                                                    function f(){
                                                    echo 'f';
                                                    }

                                                    function g(){
                                                    echo 'g';
                                                    }

                                                    function h(){
                                                    echo 'h';
                                                    }

                                                    a();b();c();d();e();f();g();h();
                                                    ?>

                                                    результаты без include_once:
                                                    [timon@localhost ~]$ ab -n5000 -c5 http://localhost2/
                                                    Server Software: Apache/2.2.8
                                                    Server Hostname: localhost2
                                                    Server Port: 80

                                                    Document Path: /
                                                    Document Length: 8 bytes

                                                    Concurrency Level: 5
                                                    Time taken for tests: 6.403327 seconds
                                                    Complete requests: 5000
                                                    Failed requests: 0
                                                    Write errors: 0
                                                    Total transferred: 990198 bytes
                                                    HTML transferred: 40008 bytes
                                                    Requests per second: 780.84 [#/sec] (mean)
                                                    Time per request: 6.403 [ms] (mean)
                                                    Time per request: 1.281 [ms] (mean, across all concurrent requests)
                                                    Transfer rate: 150.86 [Kbytes/sec] received

                                                    c include_once:
                                                    [timon@localhost ~]$ ab -n5000 -c5 http://localhost2/
                                                    Server Software: Apache/2.2.8
                                                    Server Hostname: localhost2
                                                    Server Port: 80

                                                    Document Path: /
                                                    Document Length: 8 bytes

                                                    Concurrency Level: 5
                                                    Time taken for tests: 4.786561 seconds
                                                    Complete requests: 5000
                                                    Failed requests: 0
                                                    Write errors: 0
                                                    Total transferred: 990000 bytes
                                                    HTML transferred: 40000 bytes
                                                    Requests per second: 1044.59 [#/sec] (mean)
                                                    Time per request: 4.787 [ms] (mean)
                                                    Time per request: 0.957 [ms] (mean, across all concurrent requests)
                                                    Transfer rate: 201.82 [Kbytes/sec] received

                                                    apc отключен, после каждого теста делался httpd_restart и echo 1 > /proc/sys/vm/drop_caches

                                                    вопросы есть? :)
                                                    p.s. для тех кто не умеет читать цифирьки, с include на 25% быстрее
                                                      0
                                                      Не думаю, что этот пример корректен. Не против, если я его немного модифицирую, так сказать, для чистоты эксперимента. Совсем чуть-чуть.



                                                      Вариант 1 (без инклудов)


                                                      f1();
                                                      f2();
                                                      f3();
                                                      f4();
                                                      f5();
                                                      f6();
                                                      f7();
                                                      f8();

                                                      function f1() { echo 'f1'; }
                                                      function f2() { echo 'f2'; }
                                                      function f3() { echo 'f3'; }
                                                      function f4() { echo 'f4'; }
                                                      function f5() { echo 'f5'; }
                                                      function f6() { echo 'f6'; }
                                                      function f7() { echo 'f7'; }
                                                      function f8() { echo 'f8'; }

                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }
                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }
                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }
                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }
                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }
                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }
                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }
                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }

                                                      ?>



                                                      Вариант 2 (с инклудами)


                                                      include_once('./t2_1.inc.php');
                                                      include_once('./t2_2.inc.php');
                                                      include_once('./t2_3.inc.php');
                                                      include_once('./t2_4.inc.php');
                                                      include_once('./t2_5.inc.php');
                                                      include_once('./t2_6.inc.php');
                                                      include_once('./t2_7.inc.php');
                                                      include_once('./t2_8.inc.php');

                                                      f1();
                                                      f2();
                                                      f3();
                                                      f4();
                                                      f5();
                                                      f6();
                                                      f7();
                                                      f8();

                                                      ?>

                                                      В каждом файле t2_1.inc.php код соответствующей ему функции и цикл:


                                                      function f1() { echo 'f1'; }

                                                      for ($i = 1; $i < 100; $i++) { $a = 2 + $i; }

                                                      ?>


                                                      Тестовая платформа - PIII600/256Mb/ATA100/Mandrake Linux/Apache 1.3.X/PHP 4.4. Рестарт httpd соответственно перед каждым тестом. Ну а теперь результаты:

                                                      ab -c5 -n1000 http://localhost/t1.php (без инклудов)

                                                      Concurrency Level: 5
                                                      Time taken for tests: 4.166 seconds
                                                      Complete requests: 1000
                                                      Failed requests: 0
                                                      Broken pipe errors: 0
                                                      Total transferred: 132264 bytes
                                                      HTML transferred: 16032 bytes
                                                      Requests per second: 240.04 [#/sec] (mean)
                                                      Time per request: 20.83 [ms] (mean)
                                                      Time per request: 4.17 [ms] (mean, across all concurrent requests)
                                                      Transfer rate: 31.75 [Kbytes/sec] received


                                                      ab -c5 -n1000 http://localhost/t2.php (с инклудами)

                                                      Concurrency Level: 5
                                                      Time taken for tests: 5.088 seconds
                                                      Complete requests: 1000
                                                      Failed requests: 0
                                                      Broken pipe errors: 0
                                                      Total transferred: 132000 bytes
                                                      HTML transferred: 16000 bytes
                                                      Requests per second: 196.54 [#/sec] (mean)
                                                      Time per request: 25.44 [ms] (mean)
                                                      Time per request: 5.09 [ms] (mean, across all concurrent requests)
                                                      Transfer rate: 25.94 [Kbytes/sec] received


                                                      Уважаемый timosha, если PHP и откешировал 8 файлов длинной по ~80 байт, содержащих
                                                      по одной примитивной функции, это не значит, что он сделает тоже самое на "тяжелом" проекте, содержащем сотни файлов сценариев. А если один сервер будет тянуть несколько хостов с подобными проектами? Хотя, я ни в коем случае никого ни в чем не убеждаю. Вы вольны делать что хотите и использовать свои методики построения и оптимизации проектов.
                                                    0
                                                    Мало того, что ОС кеширует, так еще и PHP кеширует, причем не исходники, а итоговый байт-код.
                                                    0
                                                    > Раньше люди писали код...
                                                    Раньше — это как именно давно?
                                                      0
                                                      Да ну. Инклуды лучше, чем весь код в одном файле. Разделённый код легче читать, легче обновлять. А замедления от него, особенно если стоит тот же Зенд Оптимайзер, не почувствуешь особо. Всё кешируется.

                                                      Что же касается вообще ситуации с тем, что кодер делает, чтобы платили, то тут ничего не поделаешь. Если кодер начнёт гикствовать с оптимизацией, то не уложится в сроки. Может вообще давайте всё на асме писать, нэ?

                                                      Лично я сейчас всё ещё пытаюсь писать красивый код, чтобы не было стыдно. Но реалии жизни ведут к противному.
                                                  0
                                                  Минусуйте, минусуйте, я все равно своего мнения не изменю :) Чем обоснована критика? Давайте обсудим.
                                                    0
                                                    не считаю себя хорошим программистом, но честное слово, испытываю отвращение.
                                                    даже сам, задумываясь о последствиях, переписывал свои классы по 10 раз, чтоб все было максимально ясно и функционально.
                                                    могли бы и опытных нанять...
                                                      0
                                                      Забавный код. Функциональный кодинг, плюс волшебные названия функций. check_and_fix_broken_emails($user) особенно порадовала.

                                                      Хотя ведь работает, а значит здорово. И, наверняка, работает быстрее, чем ежели было объектным.

                                                      Хотя та же викимедия объектна, и ничего страшного.
                                                        0
                                                        if ($orientation) {
                                                        if ($post_leave_orientation) {
                                                        orientation_update_status($user, $orientation, 2);
                                                        notification_notify_exit_orientation($user);
                                                        dirty_user($user);
                                                        redirect('home.php');
                                                        } else if (orientation_eligible_exit(array('uid'=>$user)) == 2) {
                                                        orientation_update_status($user, $orientation, 1);
                                                        notification_notify_exit_orientation($user);
                                                        dirty_user($user);
                                                        redirect('home.php');
                                                        }
                                                        }

                                                        Чорт, эпичный код :)
                                                          0
                                                          Шокед)))
                                                          Индийский код, 100%!
                                                            0
                                                            непонятно, зачем юзеров пачкают.

                                                            Хотя, вообще не могу понять, что этот кусок делает :)
                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                          0
                                                          Это хорошая реклама, не более.

                                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                          Самое читаемое