如何不使用AnnotationRegistry自动加载自定义注释类?

时间:2019-01-05 14:02:35

标签: php doctrine-orm annotations composer-php autoload

我正在使用Doctrine Annotations库(不是整个Doctrine,仅是注释),并想制作一个自定义注释类。

composer.json:

public class OrderItem
{
    public string ItemID { get; set; }
    public string ItemName { get; set; }
    public string Quantity { get; set; }
    public string Discount { get; set; }
    public int Price { get; set; }
}
private OrderItem GetOrder(string itemID, string qty, string discount)
{
    OrderItem orderItem = null;

    {
        DataView dv = BS.GetDataFromDb("where Id = " + itemID);
        if(dv != null && dv.Count > 0)
        {
            orderItem = new OrderItem();
            orderItem.ItemID = itemID;
            orderItem.ItemName = dv[0]["Name"].ToString();
            orderItem.Price = int.Parse(dv[0]["Price"].ToString());
            orderItem.Quantity = qty;
            orderItem.Discount = discount;
        }
        if (dv == null || dv.Count == 0)
            MessageBox.Show("Wrong item no: " + itemID, "Unavailable Item No", MessageBoxButton.OK, MessageBoxImage.Error);
    }
    return orderItem;
}
private void btnAddOrder_Click(object sender, RoutedEventArgs e)
{
   try {
       string discount = (txtDiscount.Text.Trim() == string.Empty ? "0" : txtDiscount.Text.Trim());
       int qty = int.Parse(txtQty.Text.Trim() == string.Empty ? "0" : txtQty.Text.Trim());
       int itemNo = int.Parse(txtItemNo.Text.Trim() == string.Empty ? "0" : txtItemNo.Text.Trim());
       if (qty <=0) { 
            MessageBox.Show("Please insert valid quantity", "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
            return;
        }
        if (itemNo <= 0) {
            MessageBox.Show("Please insert valid item number", "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
            return;
        }

        OrderItem o = GetOrder(txtItemNo.Text, txtQty.Text, discount);
        if(o != null)
        { 
            grdOrderList.Items.Add(new OrderItem { ItemName = o.ItemName, Price = o.Price, Quantity = o.Quantity, Discount = o.Discount });
            if (orderItems == null)
                orderItems = new List<OrderItem>();
            orderItems.Add(o);
            txtItemNo.Text = txtQty.Text = txtDiscount.Text = string.Empty;
        }
    }
    catch (Exception ex) {
        MessageBox.Show("Error 69: "+ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

index.php:

<StackPanel Name="YourOrder">
      <StackPanel>
          <TextBox Name="txtItemNo" />
          <TextBox Name="txtQty"  />
          <TextBox Name="txtDiscount"  />                           
          <Button Name="btnAddOrder" Click="btnAddOrder_Click" Content="Add to order" ToolTip="Adds item to order" />
      </StackPanel>
      <DataGrid Name="grdOrderList">
          <DataGrid.Columns>
               <DataGridTextColumn Header="Item Name" Binding="{Binding ItemName}" MinWidth="100" IsReadOnly="True" />
               <DataGridTextColumn x:Name="hdrPrice" Header="Price" Binding="{Binding Price}" MinWidth="20" IsReadOnly="True"  CellStyle="{StaticResource DgcRight}" />
               <DataGridTextColumn x:Name="hdrQty" Header="Qty" IsReadOnly="False" MinWidth="20" Binding="{Binding Quantity}" />
               <DataGridTextColumn x:Name="hdrDiscount"  Header="Discount" Binding="{Binding Discount}" MinWidth="50" CellStyle="{StaticResource DgcRight}" />
          </DataGrid.Columns>
     </DataGrid>
</StackPanel>

entities / MyClass.php

{
  "require": {
    "doctrine/annotations": "^1.6"
  },
  "autoload": {
    "psr-4": {
      "annotations\\": "annotations",
      "entities\\": "entities"
    }
  }
}

annotations / TestAnnotation.php

<?php

require 'vendor/autoload.php';

use Doctrine\Common\Annotations\AnnotationReader;

$annotationReader = new AnnotationReader();
$reflectionClass = new ReflectionClass(entities\MyClass::class);
$classAnnotations = $annotationReader->getClassAnnotations($reflectionClass);
var_dump($classAnnotations);

它给我以下错误:

<?php

namespace entities;

use annotations\TestAnnotation;

/**
 * @TestAnnotation("123")
 */
class MyClass
{

}

我在Internet上找到的唯一解决方案是使用AnnotationRegistry :: registerLoader或类似的东西,但已弃用,因此我想以另一种方式解决问题。

2 个答案:

答案 0 :(得分:2)

一种解决注册加载程序的方法是在应用程序引导期间某个地方显式require_once带有自定义批注的所有文件(这种方法在MongoDB ODM中已使用,但已被删除)。

在下一个主要版本中,annotations将依赖自动加载,因此设置不需要任何代码。要使用面向未来的代码,您可以使用:

use Doctrine\Common\Annotations\AnnotationRegistry;

if (class_exists(AnnotationRegistry::class)) {
    AnnotationRegistry::registerLoader('class_exists');
}

您可以显式地传递Composer的自动加载器,但是class_exists可以正常工作,因为Composer的自动加载器已在使用中。

答案 1 :(得分:0)

我发布了一个类似的问题并自己回答了它,因为显然答案比我想象的要模糊得多,最终花了一整天的时间来追查,尽管很容易解决:

composer require “yogarine/doctrine-annotation-autoload”
composer dump-autoload

有关详细信息,请参阅 https://stackoverflow.com/a/59966965/4538469