এঞ্জিনএক্স, পিএইচপি, মাইএসকিউএল এর ইনস্টলেশন, কনফিগারেশন এবং সার্ভার ব্লক (ভার্চুয়াল হোস্ট) তৈরি

সার্ভারের প্রাথমিক এবং ব্যাসিক কনফিগারেশন

1. নতুন তৈরি হওয়া সার্ভারে root ইউজার হিসেবে লগইন করুন নিচের কমান্ড দিয়ে

 ssh root@SERVER_IP_ADDRESS 

2. নতুন একটি ইউজার তৈরি করতে কমান্ড দিন নিচের মত। এখানে নতুন ইউজারের নাম demo

 adduser demo 

3. নতুন ইউজারকে root ইউজারের সমতুল্য অধিকার দিতে তাকে sudo গ্রুপে যুক্ত করুন

 gpasswd -a demo sudo 

4. পাসওয়ার্ডের পরিবর্তে পাবলিক কি দিয়ে অথেনটিকেশন এর ব্যবস্থা

  • আপনার লোকাল মেশিনে এক জোড়া কি তৈরি করতে কমান্ড দিন (~/.ssh ডিরেক্টরির মধ্যে তৈরি করা ভালো)
     ssh-keygen 

  • পাবলিক কি এর কন্টেন্টকে রিমোট সার্ভারে কপি করতে প্রথম এর কন্টেন্ট প্রিন্ট করতে কমান্ড দিন

     cat ~/.ssh/id_rsa.pub 

    এরপর স্বাভাবিকভাবে পুরো আউটপুট সিলেক্ট করে কপি করুন

  • সার্ভারে root ইউজার হিসেবে লগডইন থাকা অবস্থায় নিচের কমান্ড দিয়ে নতুন ইউজার হিসেবে লগইন করুন

     su - demo 

    এ অবস্থায় আপনি demo ইউজারের home ডিরেক্টরিতে থাকবেন

  • demo ইউজারের home ডিরেক্টরিতে .ssh নামের একটি ডিরেক্টরি তৈরি করতে এবং সেটার যথাযথ পারমিশন সেট করতে নিচের দুটো কমান্ড পর পর দিন:

     mkdir .ssh 

     chmod 700 .ssh 

  • ওই ডিরেক্টরির মধ্যে authorized_keys নামের ফাইল তৈরি/এডিট করুন

     vi .ssh/authorized_keys 

    এবার লোকাল মেশিনের পাবলিক কি এর কপি করা ভ্যালু এখানে পেস্ট করে ফাইলটি সেভ করুন

  • নতুন তৈরি হওয়া authorized_keys ফাইলের যথাযথ পারমিশন সেট করুন

     chmod 600 .ssh/authorized_keys 

  • এবার নিচের কমান্ড দিয়ে demo ইউজার থেকে লগআউট করে root ইউজারে সুইচ ব্যাক করুন:

     exit 

5. SSH কনফিগার করে root লগইন ডিস্যাবল করা

  • কফিগারেশন ফাইলটি ওপেন করার জন্য কমান্ড দিনঃ
     vi /etc/ssh/sshd_config 
  • নিচের লাইনটি খুঁজে বের করে এর ভ্যালু হিসেবে no সেট করে দিনঃ
     PermitRootLogin no 
  • SSH রিস্টার্ট করুনঃ
     service ssh restart 

##nginx, MySQL, PHP ইন্সটলেশন

1. ওয়েব সার্ভার হিসেবে Nginx ইন্সটল করা

  • ইন্সটলেশনঃ
     sudo apt-get update 
     sudo apt-get install nginx 

  • ইন্সটলেশন টেস্ট করতে নিচের ইউআরএল ব্রাউজ করুনঃ

     http://server_domain_name_or_IP 

2. DBMS হিসেবে MySQL ইন্সটল করা

  • ইন্সটলেশনঃ
     sudo apt-get install mysql-server php5-mysql

  • MySQL এর প্রয়োজনীয় ডিরেক্টরি স্ট্রাকচার তৈরিঃ

     sudo mysql_install_db 

  • একটি সাধারণ সিকিউরিটি স্ক্রিপ্ট রান করে কিছু ডিফল্ট এবং ইন্সিকিউরড সেটিং চেক/পরিবর্তন করাঃ

     sudo mysql_secure_installation 

3. fpm টুলস

  • php5-fpm, যার পূর্ণ নাম “fastCGI process manager” এর ইন্সটলেশনঃ
     sudo apt-get install php5-fpm 

  • PHP প্রসেসর এর ব্যাসিক কনফিগারেশনঃ

    • কফিগারেশন ফাইল ওপেন করুনঃ
       sudo nano /etc/php5/fpm/php.ini 

    • নিচের লাইনে শূন্য সেট করে পরিবর্তন আনুনঃ

       cgi.fix_pathinfo=0 

    • php5-fpm কে রিস্টার্ট করুনঃ

       sudo service php5-fpm restart 

4. PHP প্রসেসরকে ব্যাবহারের জন্য Nginx এর ব্যাসিক কনফিগারেশন

  • Nginx এর ডিফল্ট সার্ভার ব্লক কনফিগারেশন ফাইল ওপেন করুনঃ
     sudo nano /etc/nginx/sites-available/default 

  • যথাযথ এবং সাধারণ কিছু পরিবর্তন শেষে ফাইলটি নিচের মত হওয়া বাঞ্ছনীয়ঃ

    	server {
    	    listen 80 default_server;
    	    listen [::]:80 default_server ipv6only=on;
    	
    	    root /usr/share/nginx/html;
    	    index index.php index.html index.htm;
    	
    	    server_name server_domain_name_or_IP;
    	
    	    location / {
    	        try_files $uri $uri/ =404;
    	    }
    	
    	    error_page 404 /404.html;
    	    error_page 500 502 503 504 /50x.html;
    	    location = /50x.html {
    	        root /usr/share/nginx/html;
    	    }
    	
    	    location ~ \.php$ {
    	        try_files $uri =404;
    	        fastcgi_split_path_info ^(.+\.php)(/.+)$;
    	        fastcgi_pass unix:/var/run/php5-fpm.sock;
    	        fastcgi_index index.php;
    	        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    	        include fastcgi_params;
    	    }
    	}
    	

  • Nginx ওয়েব সার্ভারকে রিস্টার্ট করুনঃ

     sudo service nginx restart 

5. একটি PHP ফাইল দিয়ে সেটআপ টেস্ট করা

  • Nginx এর ডকুমেন্ট রুটে info.php নামের একটি নতুন ফাইল তৈরি করুনঃ
     sudo nano /usr/share/nginx/html/info.php 

  • ওই নতুন ফাইলের কন্টেন্ট/কোড হিসেবে নিচের ব্লক পেস্ট করুনঃ

                <?php
    
                    phpinfo();
    
                ?>
    	
    	

  • এবার ব্রাইজারে নিচের অ্যাড্রেস ব্রাউজ করুনঃ

     http://server_domain_name_or_IP/info.php 

  • যদি আপনি উপরের স্টেপে বলা অ্যাড্রেস এ গিয়ে পিএইচপি এর কনফিগারেশন সম্পর্কিত (এই সার্ভার মোতাবেক) একটি ওয়েব পেজ দেখতে পান তাহলে ধরে নেয়া যায় সব কিছু ঠিক ঠাক মতই হয়েছে। এখনকার মত info.php ফাইলকে রিমুভ করুনঃ

     sudo rm /usr/share/nginx/html/info.php 

##Nginx সার্ভার ব্লক (ভার্চুয়াল হোস্ট) সেটআপ

1. একাধিক সাইটের জন্য প্রয়োজনীয় ডকুমেন্ট ডিরেক্টরি তৈরি করা

  • সাধারণভাবে Ubuntu 14.04 এ ইন্সটল হওয়া Nginx এর একটি ডিফল্ট সার্ভার ব্লক এনাবেল থাকে। এটার কনফিগারেশনে /usr/share/nginx/html ডিরেক্টরি থেকে ডকুমেন্ট ডেলিভারির কথা বলা থাকে। আমরা এই লোকেশন ব্যবহার না করে বরং /var/www ডিরেক্টরিকে ব্যবহার করবো আমাদের একাধিক সাইটের কন্টেন্ট রাখার জন্য.
    • নিচের মত করে দুটো ডিরেক্টরি তৈরি করুনঃ
       sudo mkdir -p /var/www/example.com/html 

       sudo mkdir -p /var/www/test.com/html 

    • অ্যাক্সেস পারমিশন ঠিক করে সাধারণ ইউজারকে দিয়ে দিনঃ

       sudo chown -R $USER:$USER /var/www/example.com/html 

       sudo chown -R $USER:$USER /var/www/test.com/html 

    • ওয়েব রুট ডিরেক্টরির পারমিশন নিচের মত করে সেট করুনঃ

       sudo chmod -R 755 /var/www 

2. উদাহরণ হিসেবে প্রত্যেকটি সাইটের জন্য একটি করে ওয়েব পেজ তৈরি

  • প্রথম সাইটের জন্য একটি index.html তৈরি করুনঃ
    • ফাইল তৈরি করুনঃ
       nano /var/www/example.com/html/index.html

    • ফাইলের কন্টেন্ট হিসেবে নিচের কোড ব্যবহার করতে পারেনঃ

      <html>
          <head>
      	    <title>Welcome to Example.com!</title>
          </head>
          <body>
      	    <h1>Success!  The example.com server block is working!</h1>
          </body>
      </html>
      		

  • দ্বিতীয় সাইটের জন্যও আগের মতই একটি সাধারণ পেজ হলেই চলবে। আর তাই আগের ফাইলকে কপি করে দ্বিতীয় সাইটের জন্য ঠিক করা ডকুমেন্ট রুটে রাখুন

    • আগের ফাইলকে কপি করুনঃ
       cp /var/www/example.com/html/index.html /var/www/test.com/html/ 

    • নতুন ফাইলকে একটু মডিফাই করে পরিবর্তন আনুন যাতে চিন্তে সুবিধা হয়ঃ

       nano /var/www/test.com/html/index.html 

    • নিচের মত কন্টেন্ট ব্যবহার করতে পারেনঃ

      		<html>
      		    <head>
      		        <title>Welcome to Test.com!</title>
      		    </head>
      		    <body>
      		        <h1>Success!  The test.com server block is working!</h1>
      		    </body>
      		</html>
      		

3. প্রত্যেক ডোমেইনের জন্য Nginx এ সার্ভার ব্লক তৈরি

  • প্রথম সাইটের জন্য প্রথম সার্ভার ব্লক তৈরি করতে ডিফল্ট ফাইলটিকেই কপি করতে পারেন
    • কপি করুনঃ
       sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com 

    • নতুন ফাইলে প্রয়োজনীয় পরিবর্তন আনতে নিচের মত কমান্ড দিনঃ

       sudo nano /etc/nginx/sites-available/example.com 

    • পরিবর্তন আনা শেষে ফাইলের কন্টেন্ট নিচের মত করে নিনঃ

      		server {
      		    listen 80 default_server;
      		    listen [::]:80 default_server ipv6only=on;
      		
      		    root /var/www/example.com/html;
      		    index index.html index.htm;
      		
      		    server_name example.com www.example.com;
      		
      		    location / {
      		        try_files $uri $uri/ =404;
      		    }
      		}	
      		

  • দ্বিতীয় সাইটের জন্য দ্বিতীয় সার্ভার ব্লক তৈরি

    • কাজের সুবিধার জন্য প্রথম সার্ভার ব্লক ফাইলকেই কপি করুনঃ
       sudo cp /etc/nginx/sites-available/example.com /etc/nginx/sites-available/test.com 

    • নতুন ফাইলে প্রয়োজনীয় পরিবর্তন আনতে নিচের মত কমান্ড দিনঃ

       sudo nano /etc/nginx/sites-available/test.com 

      এই ফাইলের listen ডিরেক্টীভের দিকে একটু মনোযোগ দিতে হবে। যদি প্রথম ফাইলে default_server অপশন এনাবেল থাকে, তাহলে এই ফাইলে সেটি থাকা চলবে না। উপরন্তু এই ফাইলে ipv6only=on কেও রাখা যাবে না।

    • অর্থাৎ প্রয়োজনীয় পরিবর্তন শেষে নিচের মত হয়েছে কিনা লক্ষ্য করুনঃ

      		server {
      		    listen 80;
      		    listen [::]:80;
      		
      		    root /var/www/test.com/html;
      		    index index.html index.htm;
      		
      		    server_name test.com www.test.com;
      		
      		    location / {
      		        try_files $uri $uri/ =404;
      		    }
      		}
      		

4. সার্ভার ব্লক এনাবেল এবং সার্ভার রিস্টার্ট

  • নতুন তৈরি হওয়া দুটি সার্ভার ব্লককে এনাবেল করতে এগুলোর সিম্বোলিক লিঙ্ক তৈরি করে sites-enabled ডিরেক্টরিতে রাখুনঃ
     sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ 

     sudo ln -s /etc/nginx/sites-available/test.com /etc/nginx/sites-enabled/ 

  • আগের জমা থাকা ডিফল্ট সার্ভার ব্লককে ডিজ্যাবল রাখতে সেই ফাইলকে শুধুমাত্র sites-enabled ডিরেক্টরি থেকে রিমুভ করুনঃ

     sudo rm /etc/nginx/sites-enabled/default 

  • আবার Nginx কনফিগারেশন ফাইলকে আপডেট করুন

    • ফাইল ওপেন করুনঃ
       sudo nano /etc/nginx/nginx.conf 

    • নিচের লাইনকে খুঁজে বের করে সেটিকে আনকমেন্ট করুন যাতে স্টেটমেন্টটি একটিভ থাকেঃ

       server_names_hash_bucket_size 64; 

    • Nginx রিস্টার্ট করুনঃ

       sudo service nginx restart 

5. ফলাফল টেস্ট করা

সার্ভার ব্লক ঠিক ঠাক কাজ করছে কিনা তা চেক করতে নিচের দুটো সাইটের অ্যাড্রেস ভিজিট করুনঃ

 http://example.com 

 http://test.com 

লারাভেল সিম্পল টু-ডু লিস্ট

milon.im

আমার বইটা প্রকাশিত হবার পর থেকেই অনেকের কাছ থেকেই একটা অনুরোধ পেয়েছি। সেটা হচ্ছে আমার বইয়ে একটা ডেমো অ্যাপের দরকার ছিল, কিন্তু সেটা দেয়া হয় নি। তাই সবার অনুরোধ রাখতে আমি একটা সিম্পল টু-ডু অ্যাপ তৈরি করেছি। এই অ্যাপটি তৈরি করতে আমি ব্যবহার করেছি লারাভেল ফ্রেমওয়ার্ক ৫.১ ভার্সন এবং মাইসিক্যুয়েল।

এই অ্যাপটির কোড পাবেন গিটহাবে। এখানে অথেনটিকেশন, সিম্পল CRUD(Create, Read, Update, Delete) অপারেশন, রিসোর্সফুল রাউটিং, ফরম মডেল বাইন্ডিং, ফরম রিকোয়েস্ট, ফ্ল্যাশ ম্যাসেজ, পেজিনেশন সহ কিভাবে আপনি আপনার কোড গুছিয়ে লিখতে পারবেন, সে ব্যাপারে আলোকপাত করা হয়েছে।

ল্যান্ডিং পেজ ল্যান্ডিং পেজ

sign-in-page সাইন ইন পেজ

register-page রেজিস্ট্রেশন পেজ

todo-list-page টু-ডু লিস্ট পেজ

new-todo-create-page নতুন টু-ডু তৈরির পেজ

user-profile-page ইউজার প্রোফাইল পেজ

অ্যাপটি আপনার পিসিতে রান করতে হলে প্রথমেই গিটহাবে রিপোজিটরিটি ফর্ক করুন, তারপর ক্লোন করতে নিচের কমান্ডটি দিন-

এরপর ঐ ডিরেক্টরিতে প্রবেশ করুন নিচের কমান্ডটির মাধ্যমে-

এরপর .env ফাইলটি তৈরি করুন নিচের কমান্ডটির মাধ্যমে-

এবার .env ফাইলে আপনার প্রয়োজনীয় পরিবর্তন করে নিন। শুধুমাত্র DB_USERNAME এবং DB_PASSWORD এই…

View original post 83 more words

Yii ফ্রেমওয়ার্ক সম্পর্কে কিছু কথা

yii2

Yii ফ্রেমওয়ার্ক সম্পর্কে কিছু কথাঃ

“Yii” হল একটা ওপেন সোর্স অবজেক্ট ওরিয়েন্টেড উচ্চ ক্ষমতা সম্পন্ন পিএইসপি ফ্রেমওয়ার্ক যেটা দ্রুত ওয়েব অ্যাপ্লিকেশন তৈরির জন্য ব্যবহৃত হয়। Yii এর উচ্চারন হল “Yee” অথবা [ji:] (চাইনিজ ভাষায়) আর এটার অর্থ “সিম্পল এ্যান্ড এভোলুশনারি” (চাইনিজ ভাষায়)। এটার অর্থ “ইয়েস ইট ইস” (ইংরেজীতে)।

“Yii” ফ্রেমওয়ার্ক এর ফিচার্সঃ

১. মডেল ভিউ কন্ট্রোলার ডিজাইন প্যাটার্ন।
২. ডাটাবেজ এক্সেস অবজেক্ট, কুয়েরি বিল্ডার, এক্টিভ রেকর্ড, ডিবি মাইগ্রেশন।
৩. ফর্ম ইনপুট এ্যান্ড ভেলিডেশন।
৪. এজাক্স এনাবল্ড উইগেট।
৫. অ্যাথেন্টিকেশন এ্যান্ড অ্যাথোরাইজেশন।
৬. স্কিনিং এ্যান্ড থিমিং।
৭. ওয়েব সার্ভিসেস।
৮. ইন্টারন্যাশনালাইজেশন এ্যান্ড লোকালাইজেশন।
৯. লেয়ার্ড ক্যাচিং স্কিম।
১০. এরর হ্যান্ডেলিং এ্যান্ড লগিং।
১১. সিকুউরিটি।
১২. ইউনিট এ্যান্ড ফাংশনালিটি টেস্টিং।
১৩. অ্যাটোমেটিক কোড জেনারেশন।
১৪. ফ্রেন্ডলি উইথ থার্ড পার্টি কোড।
১৫. ডিটেইল্ড ডকুমেন্টেশন।
১৬. এক্সটেনশন লাইব্রেরী।

আমি ব্যাক্তিগতভাবে যে কারনে “Yii” ফ্রেমওয়ার্ক এ কাজ করতে পছন্দ করিঃ

১. ক্রুড জেনারেটর (এটা আপনাদেরকে মডেল, ভিউ, কন্ট্রোলার তৈরি করতে সাহায্য করবে)।
২. বিল্ড-ইন টুইটার বুটস্ট্রাপ।
৩. ফর্ম ভেলিডেশন সার্ভার ও ক্লায়েন্ট উভয় দিকে বিল্ড-ইন ভাবে করে থাকে (ফর্ম হেল্পার এর মাধ্যমে)।
৪. বিল্ড-ইন রোল বেসড একসেস কন্ট্রোল (এটার সাহায্যে ইউজার এর রোল, গ্রুব ও পলিছি নির্ধারণ করতে পারবেন)।
৫. ডাটাবেস এক্টিভ রেকর্ড (অবজেক্ট রিলেশনাল ম্যাপার)।
৬. স্টেবিলিটিঃ এখানে স্টেবিলিটি বলতে এটার ভার্সনকে বুঝানো হয়েছে। অন্যান্য ফ্রেমওয়ার্ক এর মত এটি দ্রুত পরিবর্তিত হয়না। যেমনঃ ২ থেকে ৩ কিংবা ৪ থেকে ৫, যাতে করে আপনাকে আপনার প্রজেক্ট নিয়ে চিন্তিত থাকতে হবেনা সুধু মাইনর কিছু পরিবর্তন করলেই আপনি ভার্সন আপগ্রেড করতে পারবেন।

এবং আরও অনেক ফিচার।

এতক্ষণ আমি আপনাদেরকে সুধু “Yii” সম্পর্কে বললাম। এখন আমি আপনাদেরকে Yii2 সম্পর্কে সামান্য ধারণা দিতে চাচ্ছি। আমি জানি আমাদের মধ্যে অনেকেই “Yii” ব্যাবহার করেছি।

“Yii2” হল “Yii1” এর রি-রাইট করা। এটি রান করতে পিএইসপি নুন্যতম ৫.৪ লাগে। “Yii2” পিএইসপি নুন্যতম ৫.৪ সাপোর্ট করার জন্য পিএইসপির মোটামুটি সকল প্রকার নতুন ফিচার ব্যাবহার করা হয়েছে। “Yii1” পিএইসপির পুরানো ভার্সন ব্যাবহার করত আর এজন্য নতুন ওয়েব টেকনোলোজি থেকে অনেক পিছিয়ে ছিল। এক কথায় বলা যায় পিএইসপির অন্যান্য ফ্রেমওয়ার্ক সিম্ফোনী, লারাভেল এর নতুন ভার্সন থেকে এটা পিছিয়ে ছিল। আর বর্তমান টেকনোলোজির সাথে খাপ খাইয়ে চলার জন্যই “Yii2” ডেভেলপ করা হয়। আর “Yii2” তে এখন কম্পোজার থেকে শুরু করে, ডাটাবেস মাইগ্রেশন, স্কিমা তৈরি, নেমস্পেস এর সঠিক ব্যাবহার, পিএইসপির ফুল অবজেক্ট অরিয়েন্টেট এর ব্যাবহার করা হয়েছে।

আপনারা কম্পোজার ব্যাবহার করে খুব সহজেই এইটা ইন্সটল করে নিতে পারবেন।

এর জন্য নিচের কমান্ডটা লিখতে হবে আপনার প্রজেক্টের ডিরেক্টোরিতে গিয়ে টার্মিনাল কিংবা কমান্ড প্রম্পড থেকে।

php composer.phar global require "fxp/composer-asset-plugin:1.0.0"

[বিঃদ্রঃ উপরের কমান্ডটি কম্পোজার এ্যাসেট প্লাগিন ইনস্টল করার জন্য]

php composer.phar create-project yiisoft/yii2-app-basic basic 2.0.3

অথবা

php composer.phar create-project yiisoft/yii2-app-advanced advanced 2.0.3

[বিঃদ্রঃ আপনার মেশিনে পিএইসপি আর কম্পোজার ঠিকঠাক মত কনফিগার করা থাকলে এইভাবে লিখলেই হবে ]

composer create-project yiisoft/yii2-app-basic basic 2.0.3

১ম (বেসিক) টি হল ফ্রন্ট এন্ড টেমপ্লেট বেসড অ্যাপ্লিকেশন তৈরি করার জন্য আর ২য় (আডভান্সড) টি হল ফ্রন্ট এন্ড + ব্যাক এন্ড টেমপ্লেট বেসড অ্যাপ্লিকেশন তৈরি করার জন্য।

২য় টি ব্যাবহার করলে আপনাকে নতুন করে ইউজার লগিন ও রেজিস্ট্রেশন নিয়ে কাজ করতে হবে না সুধু আপনার পছন্দমত পরিবর্তন করে নিলেই হবে ।

আপনারা নিজে নিজে ক্রুড জেনারেটর ট্রাই করে দেখবেন। এটা আপনাদের ডেভেলপ সময় অনেক বাচিয়ে দিবে কারণ এটা বেসিস এইসটিএমএল ভিউ সহ সব কিছু আপনার জন্য রেডি করে রাখবে সুধু আপনার পছন্দমত একটু পরিবর্তন করে নিলেই হবে। “Yii2” কিংবা “Yii” তে জেনারেটর ব্যাবহার করার জন্য “Gii” নামক টুলটি

ব্যাবহার করতে হবে এই লিংক থেকে এটি সম্পর্কে ধারনা পাবেন।

সময় সল্পতার কারনে আমি আপনাদেরকে পুর বিষয়ে টিউটোরিয়ালের মাধ্যমে দেখাইতে পারলামনা।

নিচে কিছু লিংক দিয়ে দিলাম ওইখান থেকে দেখে নিবেন আশা করি আপনাদের ভাল লাগবে এই ফ্রেমওয়ার্কটি ইনশাল্লাহ।।

http://www.yiiframework.com/doc-2.0/guide-index.html
http://stuff.cebe.cc/yii2-guide.pdf
http://www.yiiframework.com/doc-2.0/guide-start-gii.html
http://www.yiiframework.com/doc-2.0/guide-security-authorization.html

জাভা কিভাবে কাজ করে

Java-drawn-logo

জাভা কোড প্রথমে বাইটকোড এ কম্পাইল হয়, তারপর সেটিকে জাভা ভার্চুয়াল মেশিন এক্সিকিউট করে। বাইটকোড হচ্ছে এক ধরণের ইন্টারমিডিয়েড ল্যাংগুয়েজ যা কিনা ঠিক হিউম্যান রিডএবল ও না, আবার মেশিন রিডএবলও না। এটি শুধুমাত্র জাভা ভার্চুয়াল মেশিন (JVM) পড়তে পারে। বাইটকোড কে এক্সিকিউট করার জন্যে জাভা ভার্চুয়াল মেশিন জাস্ট ইন টাইম(JIT) কম্পাইলার ব্যবহার হরে। JIT বাইটকোড কে সরাসরি ইন্টারপ্রেট করে। এটি রানটাইম-এ বাইটকোড কে ইন্টারপ্রেট করে মেশিন কোড এ রূপান্তরিত করে যা কিনা সিপিইউ রান করে। এখানে একটি ইন্টারেস্টিং প্রশ্ন হতে পারে, জাভা কি তাহলে ইন্টারেপ্রেটেট ল্যাংগুয়েজ নাকি কম্পাইল্ড ল্যাংগুয়েজ? উত্তর কিন্তু দুটোই । জাভা একি সাথে কম্পাইলড এবং ইন্টারপ্রেটেড ল্যাংগুয়েজ।

উপরের লাইনগুলো পড়ে আপনি মনে করতেই পারেন যে, JIT আসলে জাভাকে স্লো করে দিচ্ছে, কারণ এটি প্রোগ্রাম যখন চলে তখন ইন্টারপ্রেট করছে। এই উপসংহার হয়তো ইনটিউটিভ, কিন্তু সঠিক নয়। JIT আসলে অনেক ভাল ভাবেই কাজ করে।

C/C++ সাধারণভাবে ধরা হয় যে জাভা এর থেকে বেশি ভাল পারফর্ম করে। জাভা যেহেতু অন-ফ্লায় এক্সিকিউট করে , এজন্যে অনেকটা এভাবে চিন্তা করা হয়। কোড-কে মেশিন কোড-এ রূপান্তরিত করার জন্যে আসলে খুব বেশি সময় লাগে না, তারপরও যদি কোন ল্যাংগুয়েজ এর কোড-কে এক্সিকিউট করার আগে তাকে মেশিন কোড এ রূপান্তরিত করতে না হয়, তাহলে ধরা হয়, সেই ল্যাংগুয়েজ অনেকটা ফাস্টার। মজার ব্যপার হচ্ছে কোন কম্পাইলার-ই কিন্তু টপ-নচ এসেম্বলি প্রোগ্রামাররা যারা কিনা কোন হার্ডওয়্যারকে কে টার্গেট করে মেশিন কোড সরাসরি মেনিপুলেট করতে পারে, তাদের মতো মেশিন কোড তৈরি করতে পারে না, যা কিনা অনেক বেশি পার্ফরমেন্ট হবে। C/C++ কিংবা জাভা সবগুলোর-ই কিছু না কিছু ইস্যুজ আছে। জাভাকে রান করার আগে অনফ্লায় মেশিন কোড তৈরি করতে হয়, C/C++ এর কোড ও কিন্তু অনেকটা জেনেরিক ভাবেই কম্পাইলড হয়। C/C++ এ কিন্তু সরাসরি একটি নির্দিষ্ট হার্ডওয়্যারকে টার্গেট করে কোড লেখা হয় না সবসময়।

মজার ব্যপার হচ্ছে, জাভা ভার্চুয়াল মেশিন কিন্তু খুব-ই ইন্টেলিজেন্ট এনভায়রনমেন্ট এবং JIT নিজেও খুব-ই ইন্টেলিজেন্ট কম্পাইলার। উদাহরণ সরূপ- JVM জানে যে কোন মেথড কতবার কল করা হচ্ছে, কারণ এটি কাউন্ট করে । যখন এই কাউন্ট একটি নির্দিষ্ট থ্রেসহোল্ড এর বাইরে চলে যায়, তখন সেই মেথড-এর মেশিন কোড JVM রেখে দেয়, পরের বার আবার কল করা হলে, সেটি আর সেই মেথডকে ইন্টারপ্রেট না করে সরসরি সেই রেখে দেওয়া মেশিন কোড-কে দিয়ে দেয় যা কিনা বারবার বাইটকোড থেকে মেশিনকোড-এ ট্রান্সলেশান করার কস্ট কমিয়ে দেয়। আরও মজার ব্যাপার হচ্ছে, JIT কম্পাইলার, যে সব কোড খুব বেশিবার ব্যবহার করা হয়, সেগুলোকে অপটিমাইজ করে । JIT নানা ধররণের স্ট্যাটিসটিক্স কালেক্ট করে থাকে। রিসার্সে দেখা গেছে যে, 80% সময়ে আসলে মোট কোডবেইস এর 20% কোড এক্সিকিউট করা হয়। সুতরাং এই 20% কোড গুলো যদি আলাদা করা যায়, এবং এদেরকে অপটিমাইজ করা যায়, তাহলে কিন্তু হিউজ পার্মমেন্স গেইন করা যাবে। মজার ব্যপার হচ্ছে JIT আসলে তাই করে। এটি (hotcode) এই ২০% কোড কে আলাদা করতে পারে এবং এদেরকে অপটিমাইজ করতে পারে। ওরাকল এর জাভা ভার্চুয়াল মেশিন হটস্পট এর নাম হয়তো অনেকেই জানি, এবং সেটি কিন্তু নামকরণ করা হয়েছে এই জন্যে যে, এটি এই হট স্পট গুলোকে আলাদা করতে পারে। জাভা যেহেতু JVM এর জন্যে লেখা হয়, এবং JIT সেটিকে মেশিন কোড এ রূপান্তরিত করে, এটি কিন্তু রানটাইমে হার্ডওয়্যার এর ইনফরমেশান একসেস করতে পারে এবং তার উপর ভিত্তি করে অপটিমাইজ মেশিন কোড তৈরি করে পারে, যা কিনা C/C++ এর ক্ষেত্রে অনেক সময়ই সম্ভব হয়ে উঠে না।

সুতরাং উপসংখ্যার হচ্ছে, জাভা আসলে অনেক বেশি পারফর্ম করে, কিন্তু সেটা হয়তো একটি ছোট হ্যালোওয়ার্ল্ড টাইপ এপ্লিকেশান লিখলে দেখা সম্ভব হবে না, কিন্তু আমরা যদি অনেক বড়ো বড়ো এপ্লিকেশান রান করি, এটি খুব ভাল ভাবে, অন্যান্য ল্যাংগুয়েজ থেকেও অনেক বেশি ভালভাবে কাজ করবে ।

রেগুলার এক্সপ্রেশনঃ উপকারিতা ও ব্যবহারিক প্রয়োগ

উজ্জ্বল'স নোটখাতা

রেগুলার এক্সপ্রেশনঃ
নাম থেকেই বোঝা যাচ্ছে যে, রেগুলার এক্সপ্রেশন (রেজেক্স বা RegEx) আসলে কতগুলো সুনির্দিষ্ট ক্যারেকটারের (Char) সমষ্টি। এই একগুচ্ছ ক্যারেকটারের সমষ্টি একত্রে কোন নির্দিষ্ট প্যাটার্ন প্রকাশ করে যা দিয়ে কোন বিশাল প্যারাগ্রাফ থেকে কোন নির্দিষ্ট প্যাটার্নের অংশ খুঁজে বের করতে পারে। একটি সহজ উদাহরন দেখে নেওয়া যাক। যেমন ধরি, একটি ৫০০ শব্দের প্যারাগ্রাফ থেকে এমন সব শব্দ খুঁজে বের করতে হবে যেগুলোর প্রথম অক্ষর ‘N’, শেষের অক্ষর ‘L’ এবং মাঝে কমপক্ষে একটি ‘H’ থাকবে। যদি ট্র্যাডিশনাল প্রোগ্রামিং দিয়ে এ কাজটি করতে চাই তাহলে কি কি করতে হবে তা নিচে লেখা হলঃ

ধাপ ১ঃ প্যারাগ্রাফ এর প্রথম ক্যারেকটার থেকে শুরু করে একটা একটা করে সামনে আগাতে হবে।
ধাপ ২ঃ কোন শব্দের প্রথম অক্ষর যদি ‘N’ হয় তাহলে এই ইনডেক্সে একটি পয়েন্টার রাখতে হবে। এরপর এই ইনডেক্স থেকে আবার সামনে আগাতে হবে। যদি শব্দটির শেষ অক্ষরে পৌছানোর আগে ‘H’ পাওয়া যায় এবং শেষ অক্ষরটি যদি ‘L’ হয় তাহলে এটা একটি কাঙ্খিত…

View original post 872 more words

রাস্পবেরি পাই পরিচিতি ও প্রথম বুট – ভিডিও

Photo Sep 28, 11 54 16 AM
রাস্পবেরি পাই বি+ মডেলের পরিচিত, হার্ডওয়্যার রিভিউ, এর জন্য অপারেটিং সিস্টেম রেডি করা, প্রথম বুট এবং রাস্পবিয়ান এর ব্যাসিক পরিচিত

বোয়ার নিয়ে কথাবার্তা

The Storyteller

bowerবোয়ার (Bower) হল ফ্রন্ট এন্ড ডেভেলপমেন্টের সময় যেসব জাভাস্ক্রিপ্ট ফাইল বা সিএসএস ফাইল লাগে সেগুলো ম্যানেজ করার জন্য টুইটার টিমের তৈরী করা একটা প্যাকেজ ম্যানেজার টুল। বোয়ার দিয়ে খুব সহজেই অ্যাপ্লিকেশনের জন্য প্রয়োজনীয় জেএস বা সিএসএস ফাইল অ্যাড/রিমুভ করা যায়, আপগ্রেড করা যায়। এই কাজের জন্য রয়েছে বোয়ারের বিশাল প্যাকেজ রিপোজিটরি যেখানে আপনি স্ক্রিপ্ট সার্চ করতে পারবেন খুব সহজেই। এই আর্টিকেলে আমরা দেখব কিভাবে বোয়ার ব্যবহার করতে হয় 🙂

বোয়ার ইনস্টল করা
বোয়ার ইনস্টল করার জন্য আমাদের কম্পিউটারে নোডজেএস এবং এনপিএম টুল ইনস্টল করা থাকতে হবে। নোড এবং এনপিএম ইনস্টল করার জন্য আপনারা http://nodejs.org/ থেকে ইনস্টলার টি ডাউনলোড করে চালান, একইসাথে নোড এবং এনপিএম ইনস্টল হয়ে যাবে

নোড এবং এনপিএম ঠিক মত ইনস্টল হয়েছে কিনা সেটা বোঝার জন্য আপনার কমান্ড লাইন/টার্মিনাল ওপেন করে কমান্ড দিন node -v এবং npm –v । একটু খেয়াল রাখবেন যে একটিতে -v এবং আরেকটি কমান্ডে –v ব্যবহার করা হয়েছে। । সবকিছু ঠিকঠাক থাকলে আপনারা টার্মিনালে…

View original post 871 more words

parse.com এপিআই ব্যাবহার করে একটি সাধারণ জাভাস্ক্রিপ্ট ওয়েব অ্যাপ তৈরি

ভূমিকা

মোবাইল বা অন্যান্য ফ্রন্টএন্ড প্ল্যাটফর্মের জন্য অ্যাপ ডেভেলপমেন্টের সময় প্রায় অর্ধেকেরও বেশি সময় দিতে হয় ব্যাকএন্ডে অর্থাৎ ওই অ্যাপ এর জন্য ডাটাবেজ তৈরি, সার্ভার সাইড লজিক ডিপেন্ডেণ্ট অ্যাপ তৈরি, ফ্রন্টএন্ডের জন্য এপিআই প্রোভাইডার তৈরি এবং সর্বোপরি সেই সার্ভারটা ম্যানেজমেন্ট এর জন্য টিম তৈরি। এসব কিছু অন্য একটা নির্ভরযোগ্য মাধ্যমের কাছ থেকে পেয়ে গেলে আপনার মনোযোগ তখন শুধু থাকবে ফ্রন্টএন্ড অ্যাপ তৈরিতে। এরকম একটি [ব্যাকএন্ড অ্যাজ অ্যা সার্ভিস] হচ্ছে parse.com

এটা একধারে একটি অবজেক্ট বেজড ডাটা স্টোরিং প্ল্যাটফর্ম, JSON এবং অন্যান্য ফরম্যাটের ডাটা প্রোভাইডার এবং ফাইল স্টোরিং প্ল্যাটফর্ম সাথে আছে বিল্টইন রোল ভিত্তিক ইউজার ডাটা ম্যানেজমেন্ট ফিচার। আরও আছে এটার মধ্যে থেকেই পুষনোটিফিকেশন, ইন্সটলেশন ম্যানেজমেন্টের জন্য সহজ পদ্ধতি (যদি এখানে স্টোর করা ডাটা দিয়ে একটি মোবাইল অ্যাপ বানাতে চান সেজন্য)।

সবচেয়ে মজার ব্যাপার হচ্ছে এটা একটা ফ্রি সার্ভিস (৩০ এপিআই কল পার সেকেন্ড), ফেসবুকের তত্ত্বাবধানে থাকা একটি কোম্পানি এবং মোটামুটি সব রকম সফটওয়্যার ডেভেলপমেন্ট প্ল্যাটফর্মের জন্য parse এর লাইব্রেরী/এসডিকে আছে ।

আমাদের সিরিজ পোস্টের মাধ্যমে আমরা এদের জাভাস্ক্রিপ্ট SDK ব্যাবহার করে একটি ক্লায়েন্ট সাইড অ্যাপ ডেভেলপ শুরু করবো। অর্থাৎ আমাদের এই অ্যাপটি ডাটা স্টোর, এক্সেস এবং ম্যানিপুলেট করার জন্য parse.com কে ব্যাবহার করবে। আর জাভাস্ক্রিপ্ট SDK ব্যাবহার করে parse এর সাথে যোগাযোগ করবে। আর তাই আমরা আমাদের অ্যাপটি কোন সার্ভারে হোস্ট করতে বাধ্য না কারন আমাদের কোন সার্ভার সাইড স্ক্রিপ্ট লাগবে না। ঠিক এ কারনে আমরা এটিকে github -এ একটি পেজ টাইপ রিপোজিটোরি হিসেবে হোস্ট করবো যেখানে স্ট্যাটিক HTML, javascript, css ফাইল ছাড়া আর কিছুই থাকবে না। যদিও parse এও কন্টেন্ট হোস্ট করার অপশন আছে কিন্তু সেটা আমরা করবো না। আমরা অ্যাপটি github -এ হোস্ট করবো যাতে এটাতে সবাই কন্ট্রিবিউট করতে পারে এবং github খুব সুন্দর ভাবে আমাদের অ্যাপটি তাদের পেজ সার্ভার দিয়ে সার্ভ করতে পারে।

Screen Shot 2014-09-08 at 1.44.38 AM

Demo

parse.com এ অ্যাকাউন্ট খোলা ও অ্যাপ সেটআপ করা

প্রথমেই parse.com এ গিয়ে একটি অ্যাকাউন্ট খুলুন। এরপর https://www.parse.com/apps/ অ্যাড্রেসে গেলে এবং আপনার অ্যাকাউন্টের আন্ডারে কোন অ্যাপ না থাকলে নিচের মত একটি উইন্ডো আসবে,
1

নাম হিসেবে দিন bloodmap. কেন এই ধরনের নাম সেটা নিয়ে এখন মাথা না ঘামালেও চলবে 🙂 Create app বাটনে ক্লিক করলে পরের স্ক্রিনে নিচের মত একটি ইনফো উইন্ডো পাবেন যেখানে অ্যাপ আইডি এবং বিভিন্ন প্ল্যাটফর্মের কিছু কি পাবেন।
2

এখান থেকে Application ID এবং Javascript Key দুটি নোট করে রাখুন। এখন Data Browser বাটনে ক্লিক করুন যাতে করে আমরা আমাদের অ্যাপ এর ডাটাবেজ অর্থাৎ ডাটা ক্লাস গুলো দেখতে এবং ম্যানেজ করতে পারি। ওই পেজের উপরের দিকে কিছু মেনু ট্যাবের মধ্যে Settings নামের একটি ট্যাব পাবেন। সেখানে ক্লিক করুন এবং কিছু সেটিং পরিবর্তন করে নিন (অপশনাল)। যেমন,
3
Allow client class creation অপশন অফ করে আমরা ক্লায়েন্ট সাইড থেকে সরাসরি ক্লাস বা সহজ ভাবে বলতে গেলে ডাটা টেবিল তৈরির পথ বন্ধ রাখবো। আবার নিচের মত করে,
4
আমরা ইউজার রেজিস্ট্রেশনের সময় তার ইমেইল ভেরিফাই করার অপশন অন করে নিতে পারি। এতে করে রেজিস্ট্রেশন পেজ থেকে ইমেইল এবং পাসওয়ার্ড নিয়ে ইউজার ক্লাস/টেবিলে স্টোর করার সময় parse থেকে স্বয়ংক্রিয় একটি ইমেইল চলে যাবে ইউজারের ওই ইমেইল অ্যাড্রেসে এবং সেটা ভেরিফাই না করা পর্যন্ত আমাদের Data Browser এ যদি ওই ইউজার এর ডাটা চেক করি তাহলে সেখানে তার ইমেইল ফিল্ডে unverified দেখা যাবে। অর্থাৎ সিম্পল এই অপশনটি এনাবেল করে আমরা আমাদের অ্যাপ এর জন্য ইউজারদের ইমেইল ভেরিফিকেশন এর ঝামেলা খুব সহজেই দুর করলাম।
আপনার মনে প্রশ্ন আসতে পারে, ইউজার ডাটা সেভ করার তো কোন ডাটা ক্লাস বা টেবিল চোখে পরছে না আমাদের অ্যাপের Data Browser ট্যাবের আন্ডারে। parse এর ধরন মোতাবেক ডাটা গুলো নিয়ন্ত্রিত হয় Parse.Object ক্লাসের মাধ্যমে। এই Parse.Object গুলো JSON কম্প্যাটিবল কি-ভ্যালু Pair (জোড়া) ধরনের ডাটা সংরক্ষণ করে। এই ধরনের ডাটা স্ট্রাকচার স্কিমা বিহীন অর্থাৎ আমাকে আগেই জানতে হবে না সেখানে কোন “কি” বা কলামের অস্তিত্ব আছে কি নাই। কি-ভ্যালু জোড়া বানিয়ে আর সেগুলো set মেথডের মাধ্যমে ঠিক করেও একটি ডাটা সেট পুষ/সেভ করা যায়। যদি, আমরা এই ডাটা স্ট্রাকচারে posts নামের একটি টেবিল বা ডাটা ক্লাস তৈরি করতে চাই তাহলে আমাদের কে Parse.Object এর একটা সাবক্লাস বানাতে হবে Parse.Object.extend("posts") এভাবে। সে আলোচনায় আমরা পরে আসবো যখন আমাদের অ্যাপের জন্য সেরকম ক্লাস (কাস্টম) লাগবে। আমাদের প্রয়োজনীয় ক্লাস গুলোকে কাস্টম বললাম কারন parse কিছু ডাটা ক্লাস বানিয়েই রেখেছে কিছু কমন ডাটা ম্যানিলুপেশন এর কথা মাথায় রেখে। সেরকম একটি হচ্ছে Parse.User যেটা Parse.Object এরই একটি সাবক্লাস। তাই আমরা ইউজার সাইনআপ, সাইনইন, সাইনআউট এরকম কাজের জন্য এই বিল্টইন ডাটা ক্লাসকেই ব্যাবহার করবো একটু পরেই। নিচের স্ক্রিন থেকে New Class বাটনে ক্লিক করুন,
5
তাহলে নিচের মত আরেকটি উইন্ডো আসবে যেখানে সিলেক্ট করুন User এবং Create Class বাটনে ক্লিক করুন,
6
এরপরের স্ক্রিন দেখতে হবে এরকম,
7
এখানে দেখতেই পাচ্ছেন ইউজার টেবিলের জন্য কিছু কলাম রেডি হয়ে আছে। এখন সেগুলোতে ডাটা ঢুকানো আমাদের কাজ। বলে রাখা ভালো, কাস্টম ডাটা ক্লাস বানালেও কমন কিছু কলাম তৈরি করে দেয় parse. যেমন objectid, createdAt, updatedAt ইত্যাদি।

ফ্রন্ট এন্ড অ্যাপ এর কাঠামো তৈরি

এই টিউটোরিয়াল অ্যাপটির সোর্স কোড দেখলেই বুঝতে পারবেন এটাতে শুধু একটা index.html পেজ এবং UI জেনারেটের জন্য twitterbootstrap 3.2.0 সাথে ফর্ম ভ্যালিডেশনের জন্য boostrapValidator ব্যাবহার করা হয়েছে। আর jQuery.

ফাইল স্ট্রাকচার

Screen Shot 2014-09-07 at 6.06.20 PM

index.html পেজের ফুল মার্কআপ

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>bloodmap :: একটি ওপেনসোর্স ওয়েব সার্ভিস</title>

    <!-- Bootstrap -->
    <link href="bootstrap-3.2.0/css/bootstrap.min.css" rel="stylesheet">
    <!-- bootstrapValidator -->
    <link href="assets/css/bootstrapValidator.min.css" rel="stylesheet">
    <!-- Custom CSS -->
    <link href="assets/css/custom.css" rel="stylesheet">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->

    <!-- Parse Javascript SDK -->
    <script src="https://www.parsecdn.com/js/parse-1.2.19.min.js"></script>    
  </head>
    <div class="container-fluid">
      <div class="row bloodmap-profile">
        <div class="col-md-4 col-md-offset-4">
          <div class="media">
            <a class="pull-left" href="#">
              <img class="media-object" src="http://placehold.it/50x50" alt="Profile Picture">
            </a>
            <div class="media-body">
              <h4 class="media-heading">স্বাগতম আপনাকে!</h4>
              <span id="fetchedEmail"></span>
              <button type="button" class="btn btn-danger btn-xs" id="sign-out">সাইন আউট করুন</button>
            </div>
          </div>
        </div>  
      </div>      
      <div class="row bloodmap-sign-box">
        <div class="col-md-4 col-md-offset-4">
          <!-- Nav tabs -->
          <ul class="nav nav-tabs" role="tablist">
            <li class="active">
              <a href="#sign-in" role="tab" data-toggle="tab">সাইন ইন</a>
            </li>
            <li><a href="#sign-up" role="tab" data-toggle="tab">সাইন আপ</a></li>
            <li><a href="#privacy" role="tab" data-toggle="tab">গোপনীয়তা</a></li>
          </ul>

          <!-- Tab panes -->
          <div class="tab-content">
            <div class="tab-pane active" id="sign-in">
              <form class="form-horizontal" role="form" id="sign-in-form" 
                data-bv-message="সঠিক তথ্য দিন"
                data-bv-feedbackicons-valid="glyphicon glyphicon-ok"
                data-bv-feedbackicons-invalid="glyphicon glyphicon-remove"
                data-bv-feedbackicons-validating="glyphicon glyphicon-refresh" >
                <div class="alert" style="display: none;"></div>
                <div class="form-group">                  
                  <div class="col-sm-offset-1 col-sm-10">
                    <input type="email" class="form-control" id="email" name="email" placeholder="ইমেইল অ্যাড্রেস" 
                    data-bv-notempty="true"
                    data-bv-notempty-message="ইমেইল অ্যাড্রেস বাধ্যতামূলক"
                    data-bv-emailaddress="true"
                    data-bv-emailaddress-message="ইমেইল অ্যাড্রেসটি সঠিক নয়" >
                  </div>
                </div>
                <div class="form-group">                  
                  <div class="col-sm-offset-1 col-sm-10">
                    <input type="password" class="form-control" id="password" name="password" placeholder="পাসওয়ার্ড" 
                    data-bv-notempty="true"
                    data-bv-notempty-message="পাসওয়ার্ড বাধ্যতামূলক" >
                  </div>
                </div>
                <div class="form-group">
                  <div class="col-sm-offset-1 col-sm-10">
                    <button type="submit" class="btn btn-primary btn-block">সাইন ইন করুন</button>
                  </div>
                </div>
              </form>
            </div>
            <div class="tab-pane" id="sign-up">
              <form class="form-horizontal" role="form" id="sign-up-form"
                data-bv-message="সঠিক তথ্য দিন"
                data-bv-feedbackicons-valid="glyphicon glyphicon-ok"
                data-bv-feedbackicons-invalid="glyphicon glyphicon-remove"
                data-bv-feedbackicons-validating="glyphicon glyphicon-refresh">
                <div class="alert" style="display: none;"></div>
                <div class="form-group">                  
                  <div class="col-sm-offset-1 col-sm-10">
                    <input type="email" class="form-control" id="signup-email" name="signup-email" placeholder="ইমেইল অ্যাড্রেস" 
                    data-bv-notempty="true"
                    data-bv-notempty-message="ইমেইল অ্যাড্রেস বাধ্যতামূলক"
                    data-bv-emailaddress="true"
                    data-bv-emailaddress-message="ইমেইল অ্যাড্রেসটি সঠিক নয়" >
                  </div>
                </div>
                <div class="form-group">
                  <div class="col-sm-offset-1 col-sm-10">
                    <input type="password" class="form-control" id="signup-password" name="signup-password" placeholder="পাসওয়ার্ড" 
                    data-bv-notempty="true"
                    data-bv-notempty-message="পাসওয়ার্ড বাধ্যতামূলক"
                    data-bv-identical="true"
                    data-bv-identical-field="confirm-password"
                    data-bv-identical-message="পাসওয়ার্ড এবং কনফার্ম পাসওয়ার্ড এক রকম হয়নি">
                  </div>
                </div>
                <div class="form-group">
                  <div class="col-sm-offset-1 col-sm-10">
                    <input type="password" class="form-control" id="confirm-password" name="confirm-password" placeholder="পাসওয়ার্ড কনফার্ম করুন" 
                    data-bv-notempty="true"
                    data-bv-notempty-message="কনফার্ম পাসওয়ার্ড বাধ্যতামূলক"

                    data-bv-identical="true"
                    data-bv-identical-field="signup-password"
                    data-bv-identical-message="পাসওয়ার্ড এবং কনফার্ম পাসওয়ার্ড এক রকম হয়নি">
                  </div>
                </div>                
                <div class="form-group">
                  <div class="col-sm-offset-1 col-sm-10">
                    <button type="submit" class="btn btn-primary btn-block">সাইন আপ করুন</button>
                  </div>
                </div>
              </form>

            </div>
            <div class="tab-pane" id="privacy">
              <p>এটি একটি ওপেনসোর্স ওয়েব সার্ভিস যা এই টিউটোরিয়াল কোর্সের উদাহরণ হিসেবে ডেভেলপ করা হচ্ছে জাভাস্ক্রিপ্ট এবং parse.com এপিআই এর উপর ভিত্তি করে</p>
              <p>এখানে ইনপুট হিসেবে নেয়া আপনার তথ্য গুলো এনকোডেড এবং গোপন অবস্থায় থাকে। কোনভাবেই এই তথ্য অন্য মাধ্যমে হস্তান্তর হয় না।</p>
              <p>এটি ভবিষ্যতে পাবলিক ওয়েব সার্ভিস হিসেবে লঞ্চ হতে পারে।</p>
            </div>
          </div>          
        </div>
      </div>
    </div>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="bootstrap-3.2.0/js/bootstrap.min.js"></script>
    <!-- bootstrapValidator -->
    <script src="assets/js/bootstrapValidator.min.js"></script>
    <!-- js for doing parse interactiions from the client app (js app) -->
    <script src="assets/js/main.js"></script>

  </body>
</html>

আমরা যে সিঙ্গেল পেজ অ্যাপটি বানাচ্ছি সেটার পুরো মার্কআপ উপরের মত। দেখে নেই কি কি আছে এই মার্কআপে। প্রথমেই twitterbootstrap এর নিয়ম অনুযায়ী এর স্ক্রিপ্ট গুলো ইম্পোর্ট করা আছে। এর নিচে আমাদের একটু কাস্টম CSS নেয়া হয়েছে। তার পর পরেই parse এর জাভাস্ক্রিপ্ট লাইব্রেরী ইনক্লুড করা হয়েছে।
27 থেকে 40 নাম্বার লাইন পর্যন্ত একটি div ব্লক আছে যেটা আমরা ইউজার লগইন হবার পরেই শুধুমাত্র দেখাবো। 41 থেকে 136 নাম্বার পর্যন্ত একটি ট্যাব বেজড UI করা আছে যেখানে একধারে একটি সাইন ইন ফর্ম, একটি সাইন আপ ফর্ম এবং একটি প্রাইভেসি টেক্সট দেখানোর ব্যাবস্থা করা হয়েছে। এরপরেই jQuery, bootstrap এর লাইব্রেরী এবং গুরুত্বপূর্ণ main.js যেখানে আমরা parse এর সাথে যোগাযোগের সব কোড লিখব এসগুলো ইম্পোর্ট করা হয়েছে।

custom.css স্ক্রিপ্টের কোড

.bloodmap-sign-box {
	margin-top: 50px;
}

.tab-pane {
	padding-top: 20px;
}

কিছুই না শুধু আমাদের মুল UI কে একটু উপর থেকে মার্জিন দেয়া হয়েছে।

main.js স্ক্রিপ্টের প্রথম স্টেজের কোড

Parse.initialize("kZ6KW0ZZud5.....zzhiHEwS9TV7", "wKyOvv9aL3Y.....BSA9aosK1Bf3CP");

$(document).ready(function () {
	$('form').bootstrapValidator();
});

এটা হচ্ছে আমাদের main.js এর প্রাথমিক অবস্থা। প্রথমেই Parse ইনিশিলালাইজ করা হয়েছে Application ID এবং Javascript Key কে প্যারামিটার হিসেবে পাস করে দিয়ে। তারপর আমরা আমাদের দুইটি ফর্ম (সাইন ইন এর জন্য একটি, সাইন আপের জন্য একটি) কে boostrapValidator দিয়ে ভ্যালিডেট করার ব্যাবস্থা করেছি। এক্ষেত্রে এর জন্য প্রয়োজনীয় HTML5 ডাটা অ্যাট্রিবিউট গুলো আমাদের ফর্মের মার্কআপের সাথে জুড়ে দেয়া হয়েছে (খেয়াল করুন input, form এলিমেন্ট গুলো)। ঠিক এভাবেই পুরো অ্যাপটি ব্রাউজারে রান করালে আমরা একটি ট্যাব বেজড UI দেখতে পাবো যেখানে সাইন ইন বা সাইন আপ করার ফর্ম থাকবে এবং সেগুলোতে ইনপুট ডাটা ভ্যালিডেশন সেট করা থাকবে।

parse এ তৈরি ইউজার টেবিলে ডাটা সেভ করা অর্থাৎ সাইন আপ করা

এখন আমরা আমাদের main.js এর jQuery এর ডকুমেন্ট রেডি চেকের মধ্যে নিচের কোড ব্লক যুক্ত করব,

	$('#sign-up-form').bootstrapValidator().on('success.form.bv', function(e) {
        // Prevent submit form
        e.preventDefault();
        var $form     = $(e.target);
        var email = $('#signup-email').val();
        var username = $('#signup-email').val();
        var password = $('#signup-password').val();

        var user = new Parse.User();
		user.set("username", username);
		user.set("password", password);
		user.set("email", email);
		 
		user.signUp(null, {
		  success: function(user) {
		    console.log("Success: " + user.id);
		    $form.find('.alert').removeClass().addClass('alert alert-success').html('সাইন আপ সম্পন্ন হয়েছে। এখন পাসের ট্যাবে সাইন ইন করতে পারেন!').show();
		  },
		  error: function(user, error) {
		  	$form.find('.alert').removeClass().addClass('alert alert-danger').html('কিছু একটা সমস্যা হয়েছে। ভিন্ন তথ্য দিয়ে আবার চেষ্টা করুন').show();
		    console.log("Error: " + error.code + " " + error.message);
		  }
		});
    });

এখানে 1 থেকে 7 নাম্বার লাইন পর্যন্ত সাইন আপ ফর্মকে ভ্যালিডেট করে সেটার সাবমিশনের সময় ইউজার এর ইনপুট দেয়া ইমেইল, পাসওয়ার্ড জমা করা হচ্ছে email, password, username ভ্যারিয়েবলের মধ্যে। email এবং username হিসেবে আমরা ইমেইলকেই সেট করছি।
এরপর ৯ নাম্বার লাইনে আমরা Parse.User() থেকে একটি user অবজেক্ট তৈরি করছি। এরপর এর set মেথডের মাধ্যমে আমরা username, password এবং email কি -এর ভ্যালু হিসেবে ফর্ম থেকে পাওয়া ভ্যালু গুলো সেট করছি। আর 14 নাম্বার লাইনে খুব সহজেই ইউজার সাইনাপের কাজ সেরে ফেলছি user.signUp() মেথডের মাধ্যমে। এই মেথডের দুটি রিটার্ন ব্লক success এবং error কে কাজে লাগিয়ে সাইনআপ সম্পন্ন হবার ম্যাসেজ দেখাচ্ছি একটি HTML এলিমেন্টকে শো করানোর মাধ্যমে।

ইউজার সাইন ইন করা

main.js এর ডকুমেন্ট রেডি চেক করার ব্লকের মধ্যে আমরা সাইন ইন ম্যানেজ করার জন্য নিচের কোড ব্লক ইউজ করবো,


	$('#sign-in-form').bootstrapValidator().on('success.form.bv', function(e) {
        // Prevent submit form
        e.preventDefault();
        var $form     = $(e.target);
        var email = $('#email').val();
        var password = $('#password').val();

		Parse.User.logIn(email, password, {
		  success: function(user) {
		    console.log(user);
		    $form.find('.alert').removeClass().addClass('alert alert-success').html('সাইন ইন সম্পন্ন হয়েছে।').show();
		    location.reload();
		  },
		  error: function(user, error) {
		    console.log("Error: " + error.code + " " + error.message);
		    $form.find('.alert').removeClass().addClass('alert alert-danger').html('কিছু একটা সমস্যা হয়েছে। ভিন্ন তথ্য দিয়ে আবার চেষ্টা করুন').show();
		  }
		});
    });

এখানেও ঠিক আগের মত সাইন ইন ফর্ম থেকে ভ্যালিড ডাটা রিসিভ করে সেগুলো লোকাল ভ্যারিয়েবলের মধ্যে রেখে Parse.User.logIn কলের মাধ্যমে parse এর কাছে সাইন ইন রিকোয়েস্ট পাঠানো হচ্ছে। যেখানে email এবং password কে প্যারামিটার হিসেবে দেয়া হচ্ছে। আর এখানেও দুই রিটার্ন ব্লক ব্যাবহার করে সাইন ইন সম্পন্ন হলে কারেন্ট ডকুমেন্ট রিলোড করছি আর কোন এরর হলে একটা এরর ম্যাসেজ দেখাচ্ছি সাইন ইন ফর্মের উপর।

ইউজারকে সাইন আউট করা

parse API ব্যাবহার করে সাইন আউট করা একদম সহজ। এর জন্য দরকার শুধু Parse.User.logOut() কে কল করা। নিচের কোড ব্লকটি আমরা ব্যাবহার করেছি লগআউট সম্পন্ন করে ইউজারকে পুনরায় সাইনইন এবং সাইনআপ ফর্ম দেখানোর জন্য,

    $('#sign-out').click (function () {
    	Parse.User.logOut();
    	if(Parse.User.current() == null) {
    		$('.bloodmap-profile').hide('slow');
    		$('.bloodmap-sign-box').show();
    	}
    });

ইউজার লগইন সেশন ধরে রাখা

ব্রাউজারে একজন লগডইন ইউজারের ইনফরমেশন ধরে রাখার ব্যাবস্থাও করে parser। অনেকটা সার্ভার সাইড সেশনের মত। আর তাই আমরা আমাদের ডকুমেন্ট লোডের শুরুতেই চেক করে নেব কারেন্ট কোন ইউজার লগইন অবস্থায় আছে কিনা,

	var currentUser = Parse.User.current();
	if (currentUser) {
	    console.log(currentUser);
	    $('#fetchedEmail').html(currentUser.get('email'));
	    $('.bloodmap-sign-box').hide();
	} else {
	    console.log(currentUser);
	    $('.bloodmap-profile').hide();
	    $('.bloodmap-sign-box').show();
	}

যদি কোন ভ্যালিড ইউজার লগইন ইনফো থাকে তাহলে আমরা ওই ইউজার এর ইমেইল অ্যাড্রেসটি দেখাবো আমাদের index.html ফাইলের 27-40 নাম্বার লাইনের মার্কআপ শো করার মাধ্যমে। আর কেউ লগডইন না পাওয়া গেলে আমরা সাইনইন-সাইনআপ ফর্ম দেখাবো।

নিচে পুরো main.js এর কোডটি দেয়া হল

Parse.initialize("kZ6KW0ZZud5Z.....rBwzzhiHEwS9TV7", "wKyOvv9.....HIBSA9aosK1Bf3CP");

$(document).ready(function () {
	var currentUser = Parse.User.current();
	if (currentUser) {
	    console.log(currentUser);
	    $('#fetchedEmail').html(currentUser.get('email'));
	    $('.bloodmap-sign-box').hide();
	} else {
	    console.log(currentUser);
	    $('.bloodmap-profile').hide();
	    $('.bloodmap-sign-box').show();
	}

	$('#sign-up-form').bootstrapValidator().on('success.form.bv', function(e) {
        // Prevent submit form
        e.preventDefault();
        var $form     = $(e.target);
        var email = $('#signup-email').val();
        var username = $('#signup-email').val();
        var password = $('#signup-password').val();

        var user = new Parse.User();
		user.set("username", username);
		user.set("password", password);
		user.set("email", email);
		 
		user.signUp(null, {
		  success: function(user) {
		    console.log("Success: " + user.id);
		    $form.find('.alert').removeClass().addClass('alert alert-success').html('সাইন আপ সম্পন্ন হয়েছে। এখন পাসের ট্যাবে সাইন ইন করতে পারেন!').show();
		  },
		  error: function(user, error) {
		  	$form.find('.alert').removeClass().addClass('alert alert-danger').html('কিছু একটা সমস্যা হয়েছে। ভিন্ন তথ্য দিয়ে আবার চেষ্টা করুন').show();
		    console.log("Error: " + error.code + " " + error.message);
		  }
		});
    });

	$('#sign-in-form').bootstrapValidator().on('success.form.bv', function(e) {
        // Prevent submit form
        e.preventDefault();
        var $form     = $(e.target);
        var email = $('#email').val();
        var password = $('#password').val();

		Parse.User.logIn(email, password, {
		  success: function(user) {
		    console.log(user);
		    $form.find('.alert').removeClass().addClass('alert alert-success').html('সাইন ইন সম্পন্ন হয়েছে।').show();
		    location.reload();
		  },
		  error: function(user, error) {
		    console.log("Error: " + error.code + " " + error.message);
		    $form.find('.alert').removeClass().addClass('alert alert-danger').html('কিছু একটা সমস্যা হয়েছে। ভিন্ন তথ্য দিয়ে আবার চেষ্টা করুন').show();
		  }
		});
    });

    $('#sign-out').click (function () {
    	Parse.User.logOut();
    	if(Parse.User.current() == null) {
    		$('.bloodmap-profile').hide('slow');
    		$('.bloodmap-sign-box').show();
    	}
    });
});

এই সিরিজ পোস্টটির পরের চ্যাপ্টারে আমরা ইউজারদের রোল ম্যানেজমেন্ট এবং তাদের প্রোফাইলে ডাটা স্টোরের জন্য কাস্টম ডাটা ক্লাস তৈরি ও ব্যাবহার দেখবো।

এসো নিজে করি – এঞ্জিনএক্সের সাথে পিএইচপি এফপিএম ফাস্টসিজিআই মডিউল ইন্টিগ্রেশন

The Storyteller

আমরা এর আগের পর্বে দেখেছিলাম কিভাবে এঞ্জিনএক্স ইনস্টল, আপগ্রেড এবং কনফিগার করতে হয়, এবং কিভাবে স্ট্যাটিক ফাইল সার্ভ করতে হয়। এই পর্বে আমরা আলোচনা করবো কিভাবে আমরা এঞ্জিনএক্সের মাধ্যমে পিএইচপি ফাইল সার্ভ করতে হয়।

গত পর্বের শেষে আমাদের ডিফল্ট সার্ভার ব্লক ফাইলটি (/etc/nginx/sites-available/default) দেখতে ছিল নিচের মত। আমরা আজকেও এই ফাইলটি নিয়ে কাজ করব।

গত পর্বের শেষে আমাদের ডিফল্ট সার্ভার ব্লক ফাইলটি (/etc/nginx/sites-available/default) দেখতে ছিল নিচের মত। আমরা আজকেও এই ফাইলটি নিয়ে কাজ করব। তবে সার্ভার ব্লক নিয়ে কাজ করার আগে চলুন পিএইচপির ফাস্টসিজিআই মডিউল ইনস্টল করে ফেলি।

পিএইচপির ফাস্টসিজিআই মডিউল ইনস্টল করা
এই স্টেপের জন্য আমাদের সার্ভারের টার্মিনালে নিচের কমান্ডটি চালাতে হবে। যদি ঠিকমত রিপোজিটরী কনফিগার করা থাকে, তাহলে পিএইচপি-এফপিএম প্যাকেজটি সহজেই ইনস্টল হয়ে যাবে।

উপরের কমান্ডটি ফেল করলে আমাদের ম্যানুয়ালী এপিটির সোর্স লিস্ট ফাইল এডিট করতে হবে।

ডেবিয়ান ৭ এর ক্ষেত্রে

ডেবিয়ান ৬ এর ক্ষেত্রে

এবার /etc/apt/sources.list ফাইলটি সেভ করে টার্মিনালে চলে আসুন। এখন যেটা করতে হবে সেটা…

View original post 379 more words