简体   繁体   English

验证PSR-4文件/类结构(无痛地迁移到PSR-4)

[英]Validate PSR-4 file/class structure (painless migrate to PSR-4)

I have a composer package that is used in internal projects. 我有一个在内部项目中使用的作曲家软件包。 Historically all classes in this package were autoloaded via "autoload": { "classmap": ... } and have not been structured. 历史上,此包中的所有类都是通过"autoload": { "classmap": ... } ,并且尚未进行结构化。

Now I want to migrate to PSR-4. 现在,我想迁移到PSR-4。 I reordered all files and directories according to class namespaces. 我根据类名称空间对所有文件和目录进行了重新排序。 Namespaces or class names were not changed, only file locations/names were. 命名空间或类名称未更改,仅文件位置/名称被更改。

How do I validate my new file/class structure to ensure it conforms to PSR-4 and all classes are loadable via "autoload": { "psr-4": ... } ? 如何验证我的新文件/类结构,以确保其符合PSR-4,并且所有类均可通过"autoload": { "psr-4": ... } I've made a google search but did not find any tool for that. 我已经做了一个谷歌搜索,但没有找到任何工具。

Option 1 选项1

Run your tests. 运行测试。

Whenever they're automated or manual, they'll reveal any classes that are not possible to autoload. 无论它们是自动还是手动,它们都会显示所有无法自动加载的类。

Option 2 选项2

Write a simple script that would: 编写一个简单的脚本,该脚本将:

  • list all PHP classes (FQCNs) 列出所有PHP类(FQCN)
  • include the composer autoloader (with psr4 configured) 包括作曲家自动加载器(已配置psr4)
  • for each class try to call class_exists (which will trigger autoloading) 对于每个类,请尝试调用class_exists (这将触发自动加载)

If the class_exists fail for a given class, it means its namespace is not properly configured. 如果给定的类的class_exists失败,则表示其名称空间配置不正确。

I was able to solve my problem using hints from Jakub Zalas 's answer (option 2). 我能够使用Jakub Zalas的答案(选项2)中的提示解决问题。

The idea is to: 这个想法是:

  1. Copy composer's working autoload_classmap.php to autoload_classmap-orig.php . 将作曲家的工作autoload_classmap.php复制到autoload_classmap-orig.php
  2. Rearrange classes/change composer.json as required. 根据需要重新排列类/更改composer.json
  3. Test new autoload against orig classmap. 针对orig类映射测试新的自动加载。

To avoid situation when including one class' source file automaticaly defines another class (ie more than one class is defined in one file), each class should be loaded in clean php environment (separate php-cli run). 为了避免在包含一个类的源文件时自动定义另一类的情况(即,在一个文件中定义了多个类),应在干净的php环境中加载每个类(单独的php-cli运行)。

I used 2 scripts for that: 我为此使用了2个脚本:

Class autoload checker (check.php): 类自动加载检查器(check.php):

<?php

// test if a class, mentioned in autoload_classmap-orig.php at line $num,
// can be autoloaded. Exit status: 0 - ok, 4 - failed to autoload,
// 3 - no more classes in autoload_classmap-orig.php

error_reporting(0);
require_once(__DIR__ . "/vendor/autoload.php");

$num = $argv[1];

$classes = array_keys(include('autoload_classmap-orig.php'));

if (!isset($classes[$num])) {
        exit(3);
}

$current_class = $classes[$num];
echo $current_class;
if (!class_exists($current_class)) {
        exit(4);
}

exit(0);

Iterator (check.sh) 迭代器(check.sh)

#!/usr/bin/env bash

# call ./check.php until all classes are checked or max number
# of checks reached.

max=500
num=0

while true ; do
    php ./check.php $num 
    status=$?
    case $status in
        0) echo " - OK" ;;
        3) echo "\nFinished." ; break ;;
        4) echo " - CAN NOT BE AUTOLOADED" ;;
        *) echo " - UNKNOWN ERROR $status" ;;
    esac

    num=$(($num + 1))
    if [ "$num" -gt "$max" ] ; then
        echo "\nMax number of classes reached."
        break
    fi
done

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM