$http.get returns 实际 php 脚本而不是 运行 它(yeoman,grunt)

$http.get returns actual php script instead of running it (yeoman, grunt)

我正在构建一个带有文章新闻源的 "simple" AngularJS 应用程序。我的文章存储在 mysql 数据库中,我使用 php PDO 提取它们。我曾经使用 AJAX 和简单的 LAMP 配置 (php5, mysql, apache2) 来执行此操作,并且一切都按预期工作。

现在我正在尝试使用 yeoman (bower+grunt) 重建项目,当我尝试调用我的 .php 脚本时$http.get 服务,响应是实际的脚本内容(它是 returns 代码而不是 运行 查询)。

我不知道这是我的代码问题、我的 grunt 配置问题还是其他问题。到目前为止,我还没有尝试制作发行版。

相关页面如下:

观点:

<div id="articles-sidebar">
    <h2>Search articles archive:</h2>
    <form id="searchbox" method="post">
        <input name="searchword" type="text" placeholder="author, title, keyword...">
        <input type="submit" value="Search">
    </form>
    <div id="author">
    </div>
</div>
<div id="articles-feed">
</div>
<div id="comments-box">
    <form id="comment" method="post">
        <textarea name="comment-text" placeholder="Your comment..."></textarea>
        <input name="submit-comment" type="submit" value="Post Comment">
    </form>
    <div id="comments-feed">
    </div>
</div>

控制器: 'use strict';

ar.module('ptcAngularJsApp')
    .controller('ArticlesCtrl', function ($scope, $http) {
        $scope.articles = [];

        $http.get('/scripts/php/articles.php').
            success(function(response) {
                $scope.articles = response;
                console.log(response);
            }). //end http get success
            error(function(err) {
                console.log(err);
            }); //end http get error
      });

db_auth.php:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

try {
    $hostname = "localhost";
    $username = "";
    $password = "";

    $db = new PDO("mysql:host=$hostname;dbname=topdecka_PTC;charset=utf8",$username, $password);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
    echo "Error!: " . $e->getMessage() . "<br/>";
    die();
}

articles.php:

<?php

require('db_connexion.php');

//search form
if (!empty($_POST["searchword"])) {
    $searchword = $_POST["searchword"];
    $query = $db->prepare(
        'SELECT articles.title, articles.posted, articles.extract, authors.name, GROUP_CONCAT(categories.cat_name) AS cat_name
        FROM articles, authors, categories, article_categories 
        WHERE articles.author_id = authors.id
        AND articles.id = article_categories.article_id
        AND article_categories.category_id = categories.id
        AND ((title LIKE :searchword) OR (extract LIKE :searchword) OR (body LIKE :searchword) OR (name LIKE :searchword) OR (cat_name LIKE :searchword))'
        ); //end DB QUERY
    $query->execute(array(":searchword" => "%" . $searchword . "%"));
    $result = $query->fetchAll();
    //turns timestamp into integer
    for($i = 0; $i < count($result); ++$i) {
      $result[$i]['posted'] = strtotime($result[$i]['posted']);
    }
    echo json_encode($result);
    die();
} 
//article title link
else if (!empty($_POST["title"])) {
    $title = $_POST["title"];
    $query = $db->prepare(
        "SELECT articles.title, articles.posted, articles.body, authors.name, authors.img, authors.bio, GROUP_CONCAT(categories.cat_name) AS cat_name
        FROM articles INNER JOIN authors ON articles.author_id = authors.id
        INNER JOIN article_categories ON articles.id = article_categories.article_id
        INNER JOIN categories ON article_categories.category_id = categories.id
        WHERE title LIKE :title; SELECT comment.user_id, comment.text, comment.posted FROM articles RIGHT JOIN comment ON articles.id = comment.article_id
        WHERE title LIKE :title;"
        ); //end DB QUERY
    $query->execute(array(":title" => $title));
    $result = $query->fetchAll();
    $result[0]['posted'] = strtotime($result[0]['posted']);
    $query->nextRowset();
    $result2 = $query->fetchAll();

    for($x=0; $x < count($result2); $x++) {
        $result2[$x]['posted'] = strtotime($result2[$x]['posted']);
    }

    echo json_encode(array('article'=>$result, 'comments'=>$result2));
    die();
}
//loading article comments
else if (!empty($_POST["comment_load"])) {
    $comment_load = $_POST["comment_load"];
    $query = $db->prepare(
            "SELECT comment.user_id, comment.text, comment.posted FROM articles RIGHT JOIN comment ON articles.id = comment.article_id
            WHERE title LIKE :comment_load;"
        );
    $query->execute(array(":comment_load" => $comment_load));   
    $result = $query->fetchAll();
    for($x=0; $x<count($result); $x++) {
        $result[$x]['posted'] = strtotime($result[$x]['posted']);
    }
    echo json_encode($result);
    die();
}
//saving comment
else if (!empty($_POST["comment-text"])) {
    $input_text = $_POST["comment-text"];
    $query = $db->prepare(
        'INSERT INTO comment (user_id, text, article_id)
        VALUES (101, :input_text, 4);'
        );
    $query->execute(array(":input_text" => $input_text));
    echo json_encode($result);
    die();
}
//default GET article feed
else {
    $query = $db->prepare(
        'SELECT articles.title, articles.posted, articles.extract, authors.name, GROUP_CONCAT(categories.cat_name) AS cat_name
        FROM articles, authors, categories, article_categories 
        WHERE articles.author_id = authors.id
        AND articles.id = article_categories.article_id
        AND article_categories.category_id = categories.id'
        ); //end DB QUERY
    $query->execute();
    $result = $query->fetchAll();
    //turns timestamp into integer
    for($i = 0; $i < count($result); ++$i) {
      $result[$i]['posted'] = strtotime($result[$i]['posted']);
    }
    echo json_encode($result);
    die();
}

gruntfile.js

// Generated on 2015-06-21 using generator-angular 0.11.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Configurable paths for the application
  var appConfig = {
    app: require('./bower.json').appPath || 'app',
    dist: 'dist'
  };

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: appConfig,

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      js: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      },
      jsTest: {
        files: ['test/spec/{,*/}*.js'],
        tasks: ['newer:jshint:test', 'karma']
      },
      styles: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
        tasks: ['newer:copy:styles', 'autoprefixer']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: 35729
      },
      livereload: {
        options: {
          open: true,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect().use(
                '/app/styles',
                connect.static('./app/styles')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect.static('test'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= yeoman.dist %>'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: {
        src: [
          'Gruntfile.js',
          '<%= yeoman.app %>/scripts/{,*/}*.js'
        ]
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/spec/{,*/}*.js']
      }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/{,*/}*',
            '!<%= yeoman.dist %>/.git{,*/}*'
          ]
        }]
      },
      server: '.tmp'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      server: {
        options: {
          map: true,
        },
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      app: {
        src: ['<%= yeoman.app %>/index.html'],
        ignorePath:  /\.\.\//
      },
      test: {
        devDependencies: true,
        src: '<%= karma.unit.configFile %>',
        ignorePath:  /\.\.\//,
        fileTypes:{
          js: {
            block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
              detect: {
                js: /'(.*\.js)'/gi
              },
              replace: {
                js: '\'{{filePath}}\','
              }
            }
          }
      }
    },

    // Renames files for browser caching purposes
    filerev: {
      dist: {
        src: [
          '<%= yeoman.dist %>/scripts/{,*/}*.js',
          '<%= yeoman.dist %>/styles/{,*/}*.css',
          '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= yeoman.dist %>/styles/fonts/*'
        ]
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>',
        flow: {
          html: {
            steps: {
              js: ['concat', 'uglifyjs'],
              css: ['cssmin']
            },
            post: {}
          }
        }
      }
    },

    // Performs rewrites based on filerev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: [
          '<%= yeoman.dist %>',
          '<%= yeoman.dist %>/images',
          '<%= yeoman.dist %>/styles'
        ]
      }
    },

    // The following *-min tasks will produce minified files in the dist folder
    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/styles/main.css': [
    //         '.tmp/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/scripts/scripts.js': [
    //         '<%= yeoman.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },

    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          conservativeCollapse: true,
          collapseBooleanAttributes: true,
          removeCommentsFromCDATA: true,
          removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: ['*.html', 'views/{,*/}*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },

    // ng-annotate tries to make the code safe for minification automatically
    // by using the Angular long form for dependency injection.
    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/concat/scripts',
          src: '*.js',
          dest: '.tmp/concat/scripts'
        }]
      }
    },

    // Replace Google CDN references
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            '*.html',
            'views/{,*/}*.html',
            'images/{,*/}*.{webp}',
            'styles/fonts/{,*/}*.*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [
        'copy:styles'
      ],
      test: [
        'copy:styles'
      ],
      dist: [
        'copy:styles',
        'imagemin',
        'svgmin'
      ]
    },

    // Test settings
    karma: {
      unit: {
        configFile: 'test/karma.conf.js',
        singleRun: true
      }
    }
  });


  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'wiredep',
      'concurrent:server',
      'autoprefixer:server',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve:' + target]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'wiredep',
    'concurrent:test',
    'autoprefixer',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'wiredep',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    'htmlmin'
  ]);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build'
  ]

);
};

欢迎任何关于尝试使这项工作成功的想法。谢谢

改变

$http.get('/scripts/php/articles.php')

$http.get('http://YOURDOMAIN.COM/scripts/php/articles.php')

当然,您需要将 YOURDOMAIN.COM 替换为本地主机或您正在使用的任何其他域。

问题是 g运行t 没有 运行ning 我的 php 脚本。

当我 运行 grunt build 获取分发版本,然后 运行 使用 apache 的那个版本时,我的数据库查询结果很好。

我会想办法将php集成到g运行t中,这样我就可以在我的开发环境中运行它而不用每次都构建它,并更新这个一旦我开始回答。

如果其他人知道可以执行此操作的好的教程、生成器或库,请写下来。