diff --git a/php-mode.el b/php-mode.el
index 1e232db2..d50b6b2d 100644
--- a/php-mode.el
+++ b/php-mode.el
@@ -342,6 +342,12 @@ In that case set to `NIL'."
   :tag "PHP Mode Disable C Mode Hook"
   :type 'boolean)
 
+(defcustom php-mode-enable-project-local-variable t
+  "When set to `T', apply project local variable to buffer local variable."
+  :group 'php-mode
+  :tag "PHP Mode Enable Project Local Variable"
+  :type 'boolean)
+
 (defun php-mode-version ()
   "Display string describing the version of PHP Mode."
   (interactive)
@@ -1116,6 +1122,11 @@ After setting the stylevars run hooks according to STYLENAME
                (php-set-style (symbol-name coding-style)))
         (remove-hook 'hack-local-variables-hook #'php-mode-set-style-delay)))))
 
+(defun php-mode-set-local-variable-delay ()
+  "Set local variable from php-project."
+  (php-project-apply-local-variables)
+  (remove-hook 'hack-local-variables-hook #'php-mode-set-local-variable-delay))
+
 (defvar php-mode-syntax-table
   (let ((table (make-syntax-table)))
     (c-populate-syntax-table table)
@@ -1169,6 +1180,9 @@ After setting the stylevars run hooks according to STYLENAME
   ;; PHP vars are case-sensitive
   (setq case-fold-search t)
 
+  (when php-mode-enable-project-local-variable
+    (add-hook 'hack-local-variables-hook #'php-mode-set-local-variable-delay t t))
+
   ;; When php-mode-enable-project-coding-style is set, it is delayed by hook.
   ;; Since it depends on the timing at which the file local variable is set.
   ;; File local variables are set after initialization of major mode except `run-hook' is complete.
diff --git a/php-project.el b/php-project.el
index 827be72d..18115cc0 100644
--- a/php-project.el
+++ b/php-project.el
@@ -72,6 +72,19 @@
 ;; Constants
 (defconst php-project-composer-autoloader "vendor/autoload.php")
 
+;; Custom variables
+(defgroup php-project nil
+  "Major mode for editing PHP code."
+  :tag "PHP Project"
+  :prefix "php-project-"
+  :group 'php)
+
+(defcustom php-project-auto-detect-etags-file nil
+  "If `T', automatically detect etags file when file is opened."
+  :tag "PHP Project Auto Detect Etags File"
+  :group 'php-project
+  :type 'boolean)
+
 ;; Variables
 (defvar php-project-available-root-files
   '((projectile ".projectile")
@@ -104,6 +117,12 @@ STRING
   (put 'php-project-root 'safe-local-variable
        #'(lambda (v) (or (stringp v) (assq v php-project-available-root-files))))
 
+  (defvar-local php-project-etags-file nil)
+  (put 'php-project-etags-file 'safe-local-variable
+       #'(lambda (v) (or (functionp v)
+                         (eq v t)
+                         (php-project--eval-bootstrap-scripts v))))
+
   (defvar-local php-project-bootstrap-scripts nil
     "List of path to bootstrap php script file.
 
@@ -172,7 +191,6 @@ Typically it is `pear', `drupal', `wordpress', `symfony2' and `psr2'.")
   (put 'php-project-server-start 'safe-local-variable
        #'(lambda (v) (or (functionp v)
                          (php-project--eval-bootstrap-scripts v)))))
-
 
 ;; Functions
 (defun php-project--validate-php-file-as-template (val)
@@ -229,6 +247,17 @@ Typically it is `pear', `drupal', `wordpress', `symfony2' and `psr2'.")
    (t (prog1 nil
         (warn "php-project-php-file-as-template is unexpected format")))))
 
+(defun php-project-apply-local-variables ()
+  "Apply php-project variables to local variables."
+  (when (null tags-file-name)
+    (when (or (and php-project-auto-detect-etags-file
+                   (null php-project-etags-file))
+              (eq php-project-etags-file t))
+      (let ((tags-file (expand-file-name "TAGS" (php-project-get-root-dir))))
+        (when (file-exists-p tags-file)
+          (setq-local php-project-etags-file tags-file))))
+    (when php-project-etags-file
+      (setq-local tags-file-name (php-project--eval-bootstrap-scripts php-project-etags-file)))))
 ;;;###autoload
 (defun php-project-get-bootstrap-scripts ()
   "Return list of bootstrap script."