PHP рдореЗрдВ GoogleMap рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдЯрд╛рдЗрд▓реЗрдВ рдмрдирд╛рдПрдВ

рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛

рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдкрд░ рдХрд┐рд╕реА рднреА рдбреЗрдЯрд╛ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рдирд╛ рдмрд╣реБрдд рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИред рдФрд░ рд╡реИрд╕реЗ, рдФрд░ рди рдХреЗрд╡рд▓ рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди, рдХрдИ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИрдВ: рдЧреЗрдо, рдЬрд┐рдпреЛ-рд╕рд░реНрд╡рд┐рд╕реЗрдЬ, рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди, рдЖрдВрдХрдбрд╝реЗ, рдФрд░ рдмрд╣реБрдд рдХреБрдЫред рдПрдХ рддрд░рдл, рдХреИрдирд╡рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдЪреНрдЫрд╛ рдФрд░ рдЖрдзреБрдирд┐рдХ рд╣реИ, рджреВрд╕рд░реА рдУрд░, рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕рднреА рдмреЛрдзрдЧрдореНрдп рдФрд░ рдЕрдХрд▓реНрдкрдиреАрдп рд╕реАрдорд╛рдУрдВ рдХреЛ рдкрд╛рд░ рдХрд░ рд╕рдХрддреА рд╣реИ, рдЬреЛ рдРрд╕реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдЧрддрд┐ рдореЗрдВ рдХрдореА рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ, рдХреИрдирд╡рд╛рд╕ рдХреЗ рд╣рдЬрд╛рд░реЛрдВ рдмрд╣реБрднреБрдЬ "рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдзреАрдорд╛" рдХрд░рддреЗ рд╣реИрдВ, рдмреНрд░рд╛рдЙрдЬрд╝рд░ "рдореЗрдореЛрд░реА" рдЦрд╛рддреЗ рд╣реИрдВред рднрд╛рд░реА рдорд╛рддреНрд░рд╛ рдореЗрдВ, рдЖрджрд┐ред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рд╣реИ рдХрд┐, рд╣рд╛рд▓рд╛рдВрдХрд┐ рджреБрд░реНрд▓рдн рд╣реИ, рдЗрд╕реЗ "рдкреБрд░рд╛рдиреЗ" рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдХреИрдирд╡рд╛рд╕ / рдПрдЪрдЯреАрдПрдордПрд▓ 5 рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ


рдЗрд╕ рдЪрд┐рддреНрд░ рдХреА рддрд░рд╣ рдХреБрдЫ рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ, рдкреИрдорд╛рдиреЗ рдХреЛ рдХрдо рдХрд░реЗрдВ рдФрд░ рдЗрд╕ рддрд░рд╣ "рдлреНрд░реЗрдо" рдореЗрдВ рдкреЙрд▓реАрдЧрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдмрдврд╝рд╛рдХрд░ 5,000 рдХрд░реЗрдВред рджреЛ рдпрд╛ рддреАрди рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдПрдХ рдХрд╛рд░реНрдпрд╛рд▓рдп рдХрдВрдкреНрдпреВрдЯрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдирдХреНрд╢реЗ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдкрд░ рдорд░ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рдмрд╕ рдЕрдкрдиреА рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдирдХреНрд╢реЗ рдореЗрдВ рдПрдХ рдУрд╡рд░рд▓реЗ рдкрд░рдд рдЬреЛрдбрд╝рдХрд░ рдЗрд╕рд╕реЗ рдирд┐рдкрдЯ рд╕рдХрддреЗ рд╣реИрдВред



рд╕реНрд░реЛрдд рдбреЗрдЯрд╛

рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ MySQL рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ рдЬреЛ рдмрд╣реБрднреБрдЬ рдХреЗ рдХреЛрдиреЗ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд┐рдП рдЧрдП рдХреБрдЫ рдмреНрд▓реЙрдХреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдКрдкрд░ рдХреА рддрд╕реНрд╡реАрд░ рдореЗрдВ, рдпреЗрдХрд╛рддреЗрд░рд┐рдирдмрд░реНрдЧ рд╢рд╣рд░ рдХреЗ рдХреНрд╡рд╛рд░реНрдЯрд░ рдХреЗ рд╣рд╛рде рд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдЖрдХреГрддрд┐ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рд▓реИрдВрдбрдлрд┐рд▓ рдХреЗ рд▓рд┐рдП рд╢рд╣рд░ рдХреЗ рдХреЗрдВрджреНрд░ рд╕реЗ рдПрдХ рджреВрд░реА рд╣реИ, рд╣рдо рдЗрд╕реЗ рд░рдВрдЧ рдмреНрд▓реЙрдХ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдХреБрдЫ рдбреЗрдЯрд╛ рдХреЗ рджреГрд╢реНрдп рдХреЗ рд░реВрдк рдореЗрдВ (рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рд╡рд┐рдХрд▓реНрдк: рдЬрдирд╕рдВрдЦреНрдпрд╛ рдШрдирддреНрд╡, рдкрд░реНрдпрд╛рд╡рд░рдг рдкреНрд░рджреВрд╖рдг, рдЖрджрд┐)

рдХреЛрдб

рдореИрдВрдиреЗ рдХреЛрдб рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рджрд╕реНрддрд╛рд╡реЗрдЬ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рддрд╛рдХрд┐ рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛред рдПрдХ рдШрдВрдЯреЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдХреЛрдб рд╕рд╣реА рд╕реЗ рдмрд╣реБрдд рджреВрд░ рд╣реИ, рдФрд░ рдХреЗрд╡рд▓ рдпрд╣ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
<?php //    ,      mysql.php //  -    mysql, //     $db. require('mysql.php'); //      $tiles_path = '/some/path/to/web/site/root/poly-tiles/'; //       ,     . if (!file_exists($tiles_path)) { mkdir($tiles_path, 0755); } //         , //        $zooms = array(12,13,14,15,16); //      ,       //    'vertices',   '|' $query = 'SELECT * FROM map_blocks'; //      ,        $result = $db->query($query); //    while ($block = $db->fetch_array($result,1)) { //        id     $blocks[$block['blockid']] = $block; //           $verticles = explode('|',$block['vertices']); //      : foreach ($verticles as $verticle) { //      $v_coord = explode(',',$verticle); //     ,   , //        //        $lats[] = $v_coord[0]; $long[] = $v_coord[1]; } } //               ,   //    : foreach ($zooms as $zoom) { //       (    ) make_zoom_dir ($zoom); //        (  ) $bigimg = gen_map ($zoom,$blocks,$lats,$long); //            imagepng($bigimg,$tiles_path.$zoom.'/all.png'); //   ,        (  ) tile_map ($zoom,$bigimg,$blocks,$lats,$long); } //  ,    exit; /** * gen_map * *        . * * @param integer $zoom   * @param array $blocks    * @param array $lats    * @param array $long    * @return gd_image $image      */ function gen_map ($zoom,$blocks,$lats,$long) { //          $x['min'] = min($long); $y['min'] = max($lats); $x['max'] = max($long); $y['max'] = min($lats); //       (getTile  x & y) $tiles['tl'] = getTile ($zoom,$y['min'],$x['min']); $tiles['rb'] = getTile ($zoom,$y['max'],$x['max']); //        +1 (   ) $picsize_blocks['x'] = $tiles['rb']['x'] - $tiles['tl']['x'] + 1; $picsize_blocks['y'] = $tiles['rb']['y'] - $tiles['tl']['y'] + 1; //       $pict_w = $picsize_blocks['x'] * 256; $pict_h = $picsize_blocks['y'] * 256; //       180/85    , //         $world_shift['x'] = $tiles['tl']['x'] * 256; $world_shift['y'] = $tiles['tl']['y'] * 256; //  GD-image   $image = imagecreatetruecolor($pict_w, $pict_h); //       $bg = imagecolorallocatealpha($image, 255, 255, 255, 0); //      imagecolortransparent($image, $bg); //    $black = imagecolorallocate($image, 0, 0, 0); //   ,          $color1 = imagecolorallocatealpha($image, 255, 0, 0, 50); $color2 = imagecolorallocatealpha($image, 204, 0, 51, 50); $color3 = imagecolorallocatealpha($image, 153, 0, 102, 50); $color4 = imagecolorallocatealpha($image, 102, 0, 153, 50); $color5 = imagecolorallocatealpha($image, 51, 0, 204, 50); $color6 = imagecolorallocatealpha($image, 0, 0, 255, 50); //        imagefilledrectangle($image, 0, 0, $pict_w-1, $pict_h-1, $bg); //  : foreach ($blocks as $block_id=>$block_data) { //         $vertices = $block_data['vertices']; //      $verticles_data = explode('|',$vertices); //    : foreach ($verticles_data as $vert) { //        $b_coord = explode(',',$vert); //        ,    $vx = lonToX($b_coord[1], $zoom); $vy = latToY($b_coord[0], $zoom); //       'verts'   $vershiny[$block_id]['verts'][] = $vx - $world_shift['x']; $vershiny[$block_id]['verts'][] = $vy - $world_shift['y']; } //       'vcount' // (       -    , //      ,     ).  , //       . $vershiny[$block_id]['vcount'] = intval(count($vershiny[$block_id]['verts'])/2); } //          //         -      .. foreach ($vershiny as $block_id=>$b_data) { //     if,   . $block_dist = $blocks[$block_id]['distance']; if ( $block_dist >= 0 && $block_dist < 1000 ) { imagefilledpolygon($image, $b_data['verts'], $b_data['vcount'], $color1); } if ( $block_dist >= 1000 && $block_dist < 2000 ) { imagefilledpolygon($image, $b_data['verts'], $b_data['vcount'], $color2); } if ( $block_dist >= 2000 && $block_dist < 4000 ) { imagefilledpolygon($image, $b_data['verts'], $b_data['vcount'], $color3); } if ( $block_dist >= 4000 && $block_dist < 7000 ) { imagefilledpolygon($image, $b_data['verts'], $b_data['vcount'], $color4); } if ( $block_dist >= 7000 && $block_dist < 10000 ) { imagefilledpolygon($image, $b_data['verts'], $b_data['vcount'], $color5); } if ( $block_dist >= 10000 && $block_dist < 15000) { imagefilledpolygon($image, $b_data['verts'], $b_data['vcount'], $color6); } if ( $block_dist >= 15000) { imagefilledpolygon($image, $b_data['verts'], $b_data['vcount'], $black); } } //     return $image; } /** * tile_map * *       * * @param integer $zoom   * @param gd_image $img  ,    * @param array $blocks    * @param array $lats    * @param array $long    */ function tile_map ($zoom,$img,$blocks,$lats,$long) { global $tiles_path; //          $x['min'] = min($long); $y['min'] = max($lats); $x['max'] = max($long); $y['max'] = min($lats); //       (getTile  x & y) $tiles['tl'] = getTile ($zoom,$y['min'],$x['min']); $tiles['rb'] = getTile ($zoom,$y['max'],$x['max']); //      : //    for($x = $tiles['tl']['x']; $x<=$tiles['rb']['x']; $x++) { //    for($y = $tiles['tl']['y']; $y <= $tiles['rb']['y']; $y++) { //     $from_position_x = $x - $tiles['tl']['x']; $from_position_y = $y - $tiles['tl']['y']; //     $from_x = $from_position_x * 256; $from_y = $from_position_y * 256; //  GD-image  $tile = imagecreatetruecolor(256, 256); //       $bg = imagecolorallocatealpha($tile, 255, 255, 255, 0); //         // (  ) imagecopymerge($tile,$img,0,0,$from_x,$from_y,256,256,100); //    $white = imagecolorclosest ($tile, 255,255,255); //    $black = imagecolorclosest ($tile, 0,0,0); //     imagecolortransparent($tile, $bg); //       ,    imagecolortransparent($tile, $white); imagecolortransparent($tile, $black); //         X  make_zoom_x_dir ($zoom,$x); //    //   - : {$tiles_path}/{$zoom_dir}/{$x}/{$x}x{$t}.png $tile_name = make_tile_name ($zoom,$x,$y); //   ,     echo "Zoom: $zoom, $xx $y -> $tile_name\n"; //     imagepng($tile,$tile_name); //   GD-image ,      :-) imagedestroy($tile); } } //   GD-image  ,       :-) imagedestroy($img); } /** * make_tile_name * *           *      x & y * * @param integer $zoom   * @param integer $x   X * @param integer $y   Y * @return string      */ function make_tile_name ($zoom,$x,$y) { global $tiles_path; return $tiles_path.$zoom.'/'.$x.'/'.$y.'.png'; } /** * make_zoom_dir * *        * * @param integer $zoom   */ function make_zoom_dir ($zoom) { global $tiles_path; if (!file_exists($tiles_path.$zoom)) { mkdir($tiles_path.$zoom, 0755); } } /** * make_zoom_x_dir * *         X  * * @param integer $zoom   * @param integer $x   X */ function make_zoom_x_dir ($zoom,$x) { global $tiles_path; if (!file_exists($tiles_path.$zoom.'/'.$x.'/')) { mkdir($tiles_path.$zoom.'/'.$x.'/', 0755); } } /** * lonToX * * Returns longitude in pixels at a certain zoom level * * @param float $lon longitude * @param integer $zoom   */ function lonToX($lon, $zoom) { $offset = 256 << ($zoom-1); $x = round($offset + ($offset * $lon / 180)); return $x; } /** * lonToX * * Returns latitude in pixels at a certain zoom level * * @param float $lat latitude * @param integer $zoom   */ function latToY($lat, $zoom) { $offset = 256 << ($zoom-1); $y = round($offset - $offset/pi() * log((1 + sin($lat * pi() / 180)) / (1 - sin($lat * pi() / 180))) / 2); return $y; } /** * getTile * * Returns tile x & y numbers at a certain zoom level, latitude & longitude * * @param integer $zoom   * @param float $lat latitude * @param float $lon longitude */ function getTile ($zoom,$lat,$lon) { $tile['x'] = floor((($lon + 180) / 360) * pow(2, $zoom)); $tile['y'] = floor((1 - log(tan(deg2rad($lat)) + 1 / cos(deg2rad($lat))) / pi()) /2 * pow(2, $zoom)); return $tile; } /** * tilenums2latlon * * Convert tile coordinates pair to latitude, longitude. * * @param int $_xtile X coordinate of the tile. * @param int $_ytile Y coordinate of the tile. * @param itn $_zoom Zoom level. * @return Point Returns latitude and longitude as a {@link Point} object. */ function tilenums2latlon($_xtile, $_ytile, $_zoom) { $factor = pow(2.0, floatval($_zoom)); $coord['lon'] = ($_xtile * 360 / $factor) - 180.0; $lat = atan(sinh(M_PI * (1 - 2 * $_ytile / $factor))); $coord['lat'] = degrees($lat); return $coord; } /** * Utility function. Transforms degree value to radian one. * * @param float $_degrees Degree value. * @return float Radian value. */ function radians($_degrees) { return M_PI * $_degrees / 180; } /** * Utility function. Converts radians to degrees. * * @param float $_radians Radian value. * @return float Degree value. */ function degrees($_radians) { return $_radians * 180 / M_PI; } ?> 


рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

  1. рд╣рдо рдЙрд╕ рдХреНрд╖реЗрддреНрд░ рдХреА рд╕реАрдорд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░рд╛ рд╕рд╛рд░рд╛ рдбреЗрдЯрд╛ рдлрд┐рдЯ рд╣реЛрдЧрд╛
  2. рдкреНрд░рддреНрдпреЗрдХ рдЬрд╝реВрдо рд╕реНрддрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝реА рддрд╕реНрд╡реАрд░ рдмрдирд╛рдПрдВред
  3. рд╣рдо рдЗрд╕рдореЗрдВ рдЕрдкрдирд╛ рдбреЗрдЯрд╛ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ
  4. рдЗрд╕реЗ рдЫреЛрдЯреЗ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рдХрд╛рдЯреЗрдВ 256x256
  5. рд╣рдордиреЗ рдЙрдиреНрд╣реЗрдВ рдбреИрдбреАрдЬ рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛


рдлрд┐рд░ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, Google рдорд╛рдирдЪрд┐рддреНрд░ рдПрдкреАрдЖрдИ рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдорд╛рдирдЪрд┐рддреНрд░ рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдПрдВ
 var BWPolygonsOptions = { getTileUrl: function(ll, z) { var X = ll.x % (1 << z); // wrap return "http://some.host.com/poly-tiles/" + z + "/" + X + "/" + ll.y + ".png"; }, tileSize: new google.maps.Size(256, 256), isPng: true, minZoom: 12, maxZoom: 16, name: "BWPolygons", alt: "BWPolygons" }; var BWPolygonsMapType = new google.maps.ImageMapType(BWPolygonsOptions); 

рдФрд░ рдПрдХ рдУрд╡рд░рд▓реЗ рдкрд░рдд рдХреЗ рд░реВрдк рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд░реЗрдВ
  map.overlayMapTypes.insertAt(0, BWPolygonsMapType); 

Google рдореИрдк рдПрдкреАрдЖрдИ рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд╛рдХрд┐рдл рдЗрд╕ рдкрд░рдд рдХреЛ рд╕реНрд╡рд┐рдЪ рдФрд░ рдЕрдиреНрдп рд╕рдЬрд╛рд╡рдЯ рдХреЗ рд╕рд╛рде рд╣рд▓реНрдХрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдо рдЗрд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред

рдбреЗрдореЛ

рдХрд╛рдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдпрд╣рд╛рдБ рд╣реИ ред

рдЧрддрд┐

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 2,873 рдмреНрд▓реЙрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛, рдпреЗрдХрд╛рддреЗрд░рд┐рдирдмрд░реНрдЧ рд╢рд╣рд░ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЗ рднреАрддрд░ рд╕реНрдерд┐рдд рд╣реИред
12 рд╕реЗ 16 рддрдХ рдЬрд╝реВрдо рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 5,118 рд╣реИ ред
рдЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рд░рдирд┐рдВрдЧ рдЯрд╛рдЗрдо 1 рдорд┐рдирдЯ 11 рд╕реЗрдХрдВрдб рд╣реИ ред
HP Proliant DL 360 G5 рд╕рд░реНрд╡рд░ (1 Intel Xeon E5420 @ 2.50GHz, 4 GB RAM) рдкрд░ рдЬреЗрдирд░реЗрд╢рди рдХрд┐рдпрд╛ рдЧрдпрд╛

рдореБрдЭреЗ рдмреНрд▓реЙрдЧ рдкрд░ рдлреИрд╕рд▓рд╛ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд▓рдЧрд╛, рдореИрдВрдиреЗ рдЗрд╕реЗ PHP рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛, рдЬреЛ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рдЙрдкрдпреБрдХреНрдд рдПрдХ - рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред

Source: https://habr.com/ru/post/In146107/


All Articles