рдпрд╣ рдкреЛрд╕реНрдЯ рдПрдХ PHP рд╡рд░реНрдЧ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЙрдкрдирд╛рдо рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Twitter API рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЯреНрд╡рд┐рдЯрд░ рд╡рд░реНрдЧ рдПрдХ рдЕрдиреНрдп PHP рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рдХреИрд╢ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдХреА рд╕рд░рд▓ рдХреИрд╢рд┐рдВрдЧ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
рдкреЛрд╕реНрдЯ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдХреБрдЫ рдкреБрд╕реНрддрдХреЛрдВ, рд▓реЗрдЦреЛрдВ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдкреНрд░рд╛рдкреНрдд рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЬреНрдЮрд╛рди рдХреЛ рд╕рдореЗрдХрд┐рдд рдХрд░рдирд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдЕрдиреБрднрд╡реА TDD рдЪрд┐рдХрд┐рддреНрд╕рдХреЛрдВ рд╕реЗ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИ, рдЬреЛ рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдпрд╛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╕рдХрд▓ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИред
рд╕рдорд╕реНрдпрд╛ рдФрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг
рддреЛ, рдЖрдкрдХреЛ PHP рднрд╛рд╖рд╛ рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЯреНрд╡рд┐рдЯрд░ рдПрдкреАрдЖрдИ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред рдпрд╣ рднреА рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдЯреНрд╡рд┐рдЯрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд┐рд╕реА рдХреИрд╢рд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдХреИрд╢рд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдЬреАрд╡рдирдХрд╛рд▓ рдХреЗ рд╕рд╛рде рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЪреВрдВрдХрд┐ рд╡рд┐рдХрд╛рд╕ рд╢реИрдХреНрд╖рд┐рдХ рд╣реИ, рд╣рдо рд╕рд╣рдордд рд╣реИрдВ рдХрд┐ рд╕реНрдерд┐рддрд┐ рдбреЗрдЯрд╛ рдХреЛ JSON рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдХрдЪреНрдЪрд╛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
PHPUnit рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкрд░реАрдХреНрд╖рдг рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред
FileCache рдХреИрд╢рд┐рдВрдЧ рдХреНрд▓рд╛рд╕:
- рд╡рд░реНрдЧ рдХреЛ CacheInterface рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
- рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рд╕реЗрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд╣рд╛рдВ рдХреИрд╢реНрдб рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
- рдХреИрд╢ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рд╕реЗрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
- рдЧреИрд░-рдореМрдЬреВрдж рдбреЗрдЯрд╛ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╕рдордп, рдЭреВрдареЗ рдХреЛ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдореИрдВ рдХреБрдЫ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рджреВрдВрдЧрд╛ред рдЪреВрдВрдХрд┐ рдХрдИ рдХреИрд╢рд┐рдВрдЧ рд╡рд┐рдХрд▓реНрдк рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ CacheInterfaceред рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдЕрдиреНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рдмрд┐рд▓реНрдХреБрд▓ рд╕реНрдкрд╖реНрдЯ рд╣реИрдВред
рдЯреНрд╡рд┐рдЯрд░ рд╡рд░реНрдЧ:
- рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕рд╣реА URL рдХреЗ рд╕рд╛рде рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ HTTP рддрд░реАрдХреЗ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
- рдпрджрд┐ рдРрд╕реА рд╕рдВрднрд╛рд╡рдирд╛ рдореМрдЬреВрдж рд╣реИ (рдпрджрд┐ рдХреЛрдИ рдХреИрд╢рд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рддреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдХреЛ рдХреИрд╢ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдПрдХ рддреГрддреАрдп-рдкрдХреНрд╖ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЯреНрд╡рд┐рдЯрд░ рд╡рд░реНрдЧ рд╕реЗ рдЬреБрдбрд╝рд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдХреЗрд╡рд▓ рдкрд╛рд░рд┐рдд URL рдкрд░ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪреВрдВрдХрд┐ HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рдмрд╛рд╣рд░реА рдХрд╛рд░рдХреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдЕрднреА рднреА рдирд╣реАрдВ рдкрддрд╛ рд╣реИ рдХрд┐ рдРрд╕реА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд┐рдирд╛ рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рдЖрджрд┐рдо рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ
рдЪрд▓рд┐рдП FileCache рдХреНрд▓рд╛рд╕ рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд╛рд╕ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдкрд╣рд▓рд╛ рдЯреЗрд╕реНрдЯ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
public function testFileCacheClassShouldImplementCacheInterface() { $fileCache = new FileCache(); $this->assertInstanceOf('CacheInterface', $fileCache); }
рдкрд░реАрдХреНрд╖рдг рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рдФрд░ рдпрд╣ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд╛рдж рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ:
interface CacheInterface { public function save($id, $data); public function load($id); }
... рдФрд░ FileCache рд╡рд░реНрдЧ рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд╛рдж:
class FileCache implements CacheInterface { public function save($id, $data){} public function load($id) {} }
рдЖрдЧреЗ рдХреЗ рджреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдлрд┐рдХреНрд╕реЗрд╢рди рддреИрдпрд╛рд░реА рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЕрд░реНрдерд╛рддреН, рдХреИрд╢ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрдирд╛рдирд╛ рдФрд░ рд╕рд╛рдлрд╝ рдХрд░рдирд╛:
class FileCacheTest extends PHPUnit_Framework_TestCase { protected $cacheDir = './cache_data'; protected function setUp() {
рдФрд░ рдкрд░реАрдХреНрд╖рдг:
public function testSettingCacheDir() { $beforeFilesCount = count(scandir($this->cacheDir)); $fileCache = new FileCache($this->cacheDir); $fileCache->save('data_name', 'some data'); $afterFilesCount = count(scandir($this->cacheDir)); $this->assertTrue($afterFilesCount > $beforeFilesCount); }
рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдЬрд╛рдБрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХреИрд╢ рдлрд╝рд╛рдЗрд▓ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреА рдереА рдЬреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреА рдЧрдИ рдереА рдЬрдм рдлрд╝рд╛рдЗрд▓ рдХреИрд╢ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдкрд░реАрдХреНрд╖рдг рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ FileCache рд╡рд░реНрдЧ рдореЗрдВ рдиреНрдпреВрдирддрдо рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдП:
class FileCache implements CacheInterface { protected $cacheDir; public function __construct($cacheDir = '.') { $this->cacheDir = $cacheDir; } public function save($id, $data) { $filename = $this->cacheDir . '/' . $id . '.dat'; $f = fopen($filename, 'w'); fwrite($f, serialize($data)); fclose($f); return true; } }
рдирд┐рдореНрди рдкрд░реАрдХреНрд╖рдг рдЬреЛ рдХреИрд╢ рдЬреАрд╡рдирдХрд╛рд▓ рдЬрд╛рдБрдЪ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ:
public function testSettingCacheLifetime() { $lifetime = 2; $cacheData = 'data'; $cacheId = 'expires'; $fileCache = new FileCache($this->cacheDir, $lifetime); $fileCache->save($cacheId, $cacheData); $this->assertEquals($cacheData, $fileCache->load($cacheId)); sleep(3); $this->assertFalse($fileCache->load($cacheId)); }
рдкрд░реАрдХреНрд╖рдг рдЙрдирдХреЗ "рдХреНрд╖рдп" рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВ рдХреИрд╢ рдбреЗрдЯрд╛ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИред рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдЗрд╕ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдиреАрдВрдж (3) рдСрдкрд░реЗрдЯрд░ 3 рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдореЗрдВ рджреЗрд░реА рдХрд░рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╡рд┐рдХрд▓реНрдк рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдПрдХреНрд╕реЗрд╕ рд╕рдордп рдХреЛ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реИред
рдХреНрд▓рд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдХреИрд╢ рд▓рд╛рдЗрдлрдЯрд╛рдЗрдо рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдЬреЛрдбрд╝реЗрдВ:
public function __construct($cacheDir = '.', $lifetime = 3600) { $this->cacheDir = $cacheDir; $this->lifetime = $lifetime; }
рдФрд░ рд▓реЛрдб рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:
public function load($id) { $filename = $this->cacheDir . '/' . $id . '.dat'; if (time() - fileatime($filename) > $this->lifetime) { return false; } return unserialize(file_get_contents($filename)); }
рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреЛрдб рдХреЛ рд░реА-рдХреЛрдб рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ рддрд╛рдХрд┐ рдбреБрдкреНрд▓реАрдХреЗрдЯ рдХреЛрдб рдХреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЛрдб рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрд░реНрдерд╛рддреН рд▓реЛрдб рдФрд░ рд╕реЗрд╡ рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдЬреА рд╡рд┐рдзрд┐ _createFilename рдЬреЛрдбрд╝реЗрдВред рдХреЛрдб рдХрд╛ рдпрд╣ рдЯреБрдХрдбрд╝рд╛ рдкрд╣рд▓реЗ рд╣реА рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдбрд░ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рдХрд┐ рдирд┐рдЬреА рдкрджреНрдзрддрд┐ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рд╕реНрд░реЛрдд:
blog.byndyu.ru , рдореБрдЭреЗ рд╕рдЯреАрдХ рдкреЛрд╕реНрдЯ рдпрд╛рдж рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рднреА рд▓реЗрдЦ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧреА рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИрдВ)ред
protected function _createFilename($id) { return $this->cacheDir . '/' . $id . '.dat'; }
рдЕрдВрддрд┐рдо рдкрд░реАрдХреНрд╖рдг:
public function testLoadShouldReturnFalseOnNonexistId() { $fileCache = new FileCache($this->cacheDir); $fileCache->save('id', 'some data'); $this->assertFalse($fileCache->load('non_exist')); }
рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдмрд╕ рд▓реЛрдб рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рдХреЛрдб рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:
public function load($id) { $filename = $this->_createFilename($id); if (!file_exists($filename)) { return false; } if (time() - fileatime($filename) > $this->lifetime) { return false; } return unserialize(file_get_contents($filename)); }
рддреЛ, FileCache рд╡рд░реНрдЧ рдХреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рд╕рднреА рдкрд░реАрдХреНрд╖рдг, рдЖрдк рдЯреНрд╡рд┐рдЯрд░ рд╡рд░реНрдЧ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдо рдФрд░ рд╡рд┐рдХрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ
рд╣рдо рдкрд╣рд▓реА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдХрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
public function testTwitterShouldCallHttpClientWithCorrectUrl() { $httpClient = $this->getMock('HttpClientInterface'); $nickname = 'test_nick'; $twitter = new Twitter($httpClient); $httpClient ->expects($this->once()) ->method('get') ->with($this->equalTo('http://api.twitter.com/1/statuses/user_timeline.json?screen_name=' . $nickname)); $twitter->getStatuses($nickname); }
рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рдЯреНрд╡рд┐рдЯрд░ рдПрдкреАрдЖрдИ рд╕реЗ рдЬрд┐рд╕ URL рдкрд░ рдбреЗрдЯрд╛ рдХрд╛ рдирдореВрдирд╛ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рд╡рд╣ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ Http рдХреНрд▓рд╛рдЗрдВрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реНрд╡рддрдВрддреНрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рдореИрдВ Http рдХреНрд▓рд╛рдЗрдВрдЯ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирдХрд▓реА рд╡рд╕реНрддреБ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдореИрдВ рдмрддрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдХрд┐рд╕ рд╡рд┐рдзрд┐ рдХреЛ рдПрдХ рдирдХрд▓реА рд╡рд╕реНрддреБ рдкрд░, рдХрд┐рддрдиреА рдмрд╛рд░ рдФрд░ рдХрд┐рди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдк PHPUnit рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред
рдореИрдВ рдЖрдкрдХреЛ рддреБрд░рдВрдд рдПрдХ рдФрд░ рдкрд░реАрдХреНрд╖рд╛ рджреВрдВрдЧрд╛ рдЬреЛ рдЯреНрд╡рд┐рдЯрд░ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддрд╛ рд╣реИ:
public function testTwitterShouldLoadDataFromCacheIfIsPossible() { $cache = $this->getMock('CacheInterface'); $httpClient = $this->getMock('HttpClientInterface'); $nickname = 'test_nick'; $twitter = new Twitter($httpClient); $url = 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=' . $nickname; $urlMd5 = md5($url); $resultCached = array('status1', 'status2', 'status3'); $resultNotCached = array('save_to_cache'); $twitter->setCache($cache); $cache->expects($this->at(0))->method('load')->with($this->equalTo($urlMd5))->will($this->returnValue($resultCached)); $cache->expects($this->at(1))->method('load')->with($this->equalTo($urlMd5))->will($this->returnValue(false)); $httpClient->expects($this->once())->method('get')->with($this->equalTo($url))->will($this->returnValue($resultNotCached)); $cache->expects($this->once())->method('save')->with($this->equalTo($urlMd5), $this->equalTo($resultNotCached)); $this->assertEquals($resultCached, $twitter->getStatuses($nickname)); $this->assertEquals($resultNotCached, $twitter->getStatuses($nickname)); }
рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХрд╛рдлреА рдмрдбрд╝рд╛ рд╣реИред рдпрд╣рд╛рдВ рдирдХрд▓реА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред Http рдХреНрд▓рд╛рдЗрдВрдЯ рдореЙрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреИрд╢ рдХреНрд▓рд╛рд╕ рдореЙрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдпрд╣ рд╡рд░реНрдЧ рдкрд╣рд▓реЗ рд╣реА рд╡рд┐рдХрд╕рд┐рдд рд╣реЛ рдЪреБрдХрд╛ рд╣реИ (рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╕реНрд╡рддрдВрддреНрд░рддрд╛ рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВ)ред рдкрд░реАрдХреНрд╖рдг рдХреА рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдбреЗрдЯрд╛ рдХреИрд╢ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реИ, рддреЛ рдПрдЪрдЯреАрдЯреАрдкреА рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд▓реМрдЯрд╛рдП рдЧрдП рдбреЗрдЯрд╛ рдХреА рд╢реБрджреНрдзрддрд╛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред
рджреЛрдиреЛрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЯреНрд╡рд┐рдЯрд░ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:
class Twitter { protected $httpClient; protected $methodUrl = 'http://api.twitter.com/1/statuses/user_timeline.json'; protected $cache = null; public function __construct(HttpClientInterface $httpClient) { $this->httpClient = $httpClient; } public function setCache(CacheInterface $cache) { $this->cache = $cache; return $this; } public function getStatuses($nickname) { $url = $this->methodUrl . '?screen_name=' . $nickname; $cache = $this->cache; $cacheId = md5($url); $data = false; if ($cache !== null) { $data = $cache->load($cacheId); } if ($data === false) { $data = $this->httpClient->get($url); if ($cache !== null) { $cache->save($cacheId, $data); } } return $data; } }
рд╣реЛ рдЧрдпрд╛!
рджреЛрдиреЛрдВ рд╡рд░реНрдЧреЛрдВ рдХреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╡реЗ рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдп рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ file_get_contents рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг php рд╕реНрдХреНрд░рд┐рдкреНрдЯ рднреА рд▓рд┐рдЦреА рд╣реИ рдЬреЛ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИред
рдкрд░рд┐рдпреЛрдЬрдирд╛ GitHub:
github.com/xstupidkidzx/tddttl рдкрд░ рднреА рдкреЛрд╕реНрдЯ рдХреА рдЧрдИ рд╣реИ
рдЖрдкрдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ, рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рджреЗрдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рд╕рдорд╕реНрдпрд╛рддреНрдордХ рдореБрджреНрджреЗ рдЬреЛ рдореБрдЭреЗ рд╕реЛрдЪрддреЗ рд╣реБрдП рдорд┐рд▓реЗ, рдФрд░ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдкрдврд╝рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛:
- рдПрдХ рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд╡реНрдпрд╛рдкрдХ рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП? рдХреНрдпрд╛ рдПрдХ рдкрд░реАрдХреНрд╖рд╛ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╣реЛрддрд╛ рд╣реИ? рдпрд╛ рд╡рд╣ рдХрдИ рд╡рд┐рдзрд┐рдпреЛрдВ рдпрд╛ рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИ?
- рдХреНрдпрд╛ рд╣рд░ рдкрд╣рд▓реВ рдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рд╡рд┐рдзрд┐ рдпрд╛ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ рджрд┐рдП рдЧрдП рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╢реБрджреНрдзрддрд╛)? рдпрджрд┐ CacheInterface рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ FileCache рд╡рд░реНрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдкрд░реАрдХреНрд╖рдг рд╢рд╛рдорд┐рд▓ рд╣реИ, рддреЛ рдХреНрдпрд╛ рдпрд╣ рдХрд╣рдиреЗ рд▓рд╛рдпрдХ рд╣реИ?
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!